mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-15 17:47:53 +00:00
Merge pull request #187 from SyncrowIOT/SP-1509-FE-Implement-devices-status-based-on-the-selected-device-from-the-dropdown-list
Sp 1509 fe implement devices status based on the selected device from the dropdown list
This commit is contained in:
13
lib/pages/analytics/models/analytics_device.dart
Normal file
13
lib/pages/analytics/models/analytics_device.dart
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
class AnalyticsDevice {
|
||||||
|
const AnalyticsDevice({required this.name, required this.uuid});
|
||||||
|
|
||||||
|
final String uuid;
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
factory AnalyticsDevice.fromJson(Map<String, dynamic> json) {
|
||||||
|
return AnalyticsDevice(
|
||||||
|
uuid: json['uuid'] as String? ?? '',
|
||||||
|
name: json['name'] as String? ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
||||||
|
|
||||||
|
part 'analytics_devices_event.dart';
|
||||||
|
part 'analytics_devices_state.dart';
|
||||||
|
|
||||||
|
class AnalyticsDevicesBloc
|
||||||
|
extends Bloc<AnalyticsDevicesEvent, AnalyticsDevicesState> {
|
||||||
|
AnalyticsDevicesBloc(
|
||||||
|
this._analyticsDevicesService,
|
||||||
|
) : super(const AnalyticsDevicesState()) {
|
||||||
|
on<LoadAnalyticsDevicesEvent>(_onLoadAnalyticsDevices);
|
||||||
|
on<SelectAnalyticsDeviceEvent>(_onSelectAnalyticsDevice);
|
||||||
|
on<ClearAnalyticsDeviceEvent>(_onClearAnalyticsDevice);
|
||||||
|
}
|
||||||
|
final AnalyticsDevicesService _analyticsDevicesService;
|
||||||
|
|
||||||
|
Future<void> _onLoadAnalyticsDevices(
|
||||||
|
LoadAnalyticsDevicesEvent event,
|
||||||
|
Emitter<AnalyticsDevicesState> emit,
|
||||||
|
) async {
|
||||||
|
emit(const AnalyticsDevicesState(status: AnalyticsDevicesStatus.loading));
|
||||||
|
|
||||||
|
try {
|
||||||
|
final devices = await _analyticsDevicesService.getDevices(event.param);
|
||||||
|
emit(
|
||||||
|
AnalyticsDevicesState(
|
||||||
|
status: AnalyticsDevicesStatus.loaded,
|
||||||
|
devices: devices,
|
||||||
|
selectedDevice: devices.firstOrNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (devices.isNotEmpty) {
|
||||||
|
event.onSuccess(devices.first);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(
|
||||||
|
AnalyticsDevicesState(
|
||||||
|
status: AnalyticsDevicesStatus.failure,
|
||||||
|
errorMessage: e.toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSelectAnalyticsDevice(
|
||||||
|
SelectAnalyticsDeviceEvent event,
|
||||||
|
Emitter<AnalyticsDevicesState> emit,
|
||||||
|
) {
|
||||||
|
emit(
|
||||||
|
AnalyticsDevicesState(
|
||||||
|
selectedDevice: event.device,
|
||||||
|
devices: state.devices,
|
||||||
|
errorMessage: state.errorMessage,
|
||||||
|
status: state.status,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onClearAnalyticsDevice(
|
||||||
|
ClearAnalyticsDeviceEvent event,
|
||||||
|
Emitter<AnalyticsDevicesState> emit,
|
||||||
|
) {
|
||||||
|
emit(const AnalyticsDevicesState());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
part of 'analytics_devices_bloc.dart';
|
||||||
|
|
||||||
|
sealed class AnalyticsDevicesEvent extends Equatable {
|
||||||
|
const AnalyticsDevicesEvent();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final class LoadAnalyticsDevicesEvent extends AnalyticsDevicesEvent {
|
||||||
|
const LoadAnalyticsDevicesEvent({required this.param, required this.onSuccess});
|
||||||
|
|
||||||
|
final GetAnalyticsDevicesParam param;
|
||||||
|
final void Function(AnalyticsDevice device) onSuccess;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [param];
|
||||||
|
}
|
||||||
|
|
||||||
|
final class SelectAnalyticsDeviceEvent extends AnalyticsDevicesEvent {
|
||||||
|
const SelectAnalyticsDeviceEvent(this.device);
|
||||||
|
|
||||||
|
final AnalyticsDevice device;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [device];
|
||||||
|
}
|
||||||
|
|
||||||
|
final class ClearAnalyticsDeviceEvent extends AnalyticsDevicesEvent {
|
||||||
|
const ClearAnalyticsDeviceEvent();
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
part of 'analytics_devices_bloc.dart';
|
||||||
|
|
||||||
|
enum AnalyticsDevicesStatus { initial, loading, loaded, failure }
|
||||||
|
|
||||||
|
final class AnalyticsDevicesState extends Equatable {
|
||||||
|
const AnalyticsDevicesState({
|
||||||
|
this.status = AnalyticsDevicesStatus.initial,
|
||||||
|
this.devices = const [],
|
||||||
|
this.errorMessage,
|
||||||
|
this.selectedDevice,
|
||||||
|
});
|
||||||
|
|
||||||
|
final AnalyticsDevicesStatus status;
|
||||||
|
final List<AnalyticsDevice> devices;
|
||||||
|
final AnalyticsDevice? selectedDevice;
|
||||||
|
final String? errorMessage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [status, devices, errorMessage, selectedDevice];
|
||||||
|
}
|
@ -14,12 +14,20 @@ class EnergyManagementDataLoadingStrategy implements AnalyticsDataLoadingStrateg
|
|||||||
CommunityModel community,
|
CommunityModel community,
|
||||||
List<SpaceModel> spaces,
|
List<SpaceModel> spaces,
|
||||||
) {
|
) {
|
||||||
|
// Add to space tree bloc first
|
||||||
context.read<SpaceTreeBloc>().add(
|
context.read<SpaceTreeBloc>().add(
|
||||||
OnCommunitySelected(
|
OnCommunitySelected(
|
||||||
community.uuid,
|
community.uuid,
|
||||||
spaces,
|
spaces,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final spaceTreeState = context.read<SpaceTreeBloc>().state;
|
||||||
|
if (spaceTreeState.selectedCommunities.contains(community.uuid)) {
|
||||||
|
clearData(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FetchEnergyManagementDataHelper.loadEnergyManagementData(
|
FetchEnergyManagementDataHelper.loadEnergyManagementData(
|
||||||
context,
|
context,
|
||||||
communityId: community.uuid,
|
communityId: community.uuid,
|
||||||
@ -41,6 +49,13 @@ class EnergyManagementDataLoadingStrategy implements AnalyticsDataLoadingStrateg
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final spaceTreeState = context.read<SpaceTreeBloc>().state;
|
||||||
|
if (spaceTreeState.selectedCommunities.contains(community.uuid) ||
|
||||||
|
spaceTreeState.selectedSpaces.contains(space.uuid)) {
|
||||||
|
clearData(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FetchEnergyManagementDataHelper.loadEnergyManagementData(
|
FetchEnergyManagementDataHelper.loadEnergyManagementData(
|
||||||
context,
|
context,
|
||||||
communityId: community.uuid,
|
communityId: community.uuid,
|
||||||
@ -54,7 +69,7 @@ class EnergyManagementDataLoadingStrategy implements AnalyticsDataLoadingStrateg
|
|||||||
CommunityModel community,
|
CommunityModel community,
|
||||||
SpaceModel child,
|
SpaceModel child,
|
||||||
) {
|
) {
|
||||||
// Do nothing
|
// Do nothing else as per original implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -20,6 +20,12 @@ class OccupancyDataLoadingStrategy implements AnalyticsDataLoadingStrategy {
|
|||||||
spaces.isNotEmpty ? [spaces.first] : [],
|
spaces.isNotEmpty ? [spaces.first] : [],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final spaceTreeState = context.read<SpaceTreeBloc>().state;
|
||||||
|
if (spaceTreeState.selectedCommunities.contains(community.uuid)) {
|
||||||
|
clearData(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
FetchOccupancyDataHelper.loadOccupancyData(
|
FetchOccupancyDataHelper.loadOccupancyData(
|
||||||
context,
|
context,
|
||||||
communityId: community.uuid,
|
communityId: community.uuid,
|
||||||
@ -47,6 +53,13 @@ class OccupancyDataLoadingStrategy implements AnalyticsDataLoadingStrategy {
|
|||||||
..add(OnSpaceSelected(community, space.uuid ?? '', []));
|
..add(OnSpaceSelected(community, space.uuid ?? '', []));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final spaceTreeState = context.read<SpaceTreeBloc>().state;
|
||||||
|
if (spaceTreeState.selectedCommunities.contains(community.uuid) ||
|
||||||
|
spaceTreeState.selectedSpaces.contains(space.uuid)) {
|
||||||
|
clearData(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FetchOccupancyDataHelper.loadOccupancyData(
|
FetchOccupancyDataHelper.loadOccupancyData(
|
||||||
context,
|
context,
|
||||||
communityId: community.uuid,
|
communityId: community.uuid,
|
||||||
@ -66,6 +79,6 @@ class OccupancyDataLoadingStrategy implements AnalyticsDataLoadingStrategy {
|
|||||||
@override
|
@override
|
||||||
void clearData(BuildContext context) {
|
void clearData(BuildContext context) {
|
||||||
context.read<SpaceTreeBloc>().add(const SpaceTreeClearSelectionEvent());
|
context.read<SpaceTreeBloc>().add(const SpaceTreeClearSelectionEvent());
|
||||||
// FetchOccupancyDataHelper.clearAllData(context);
|
FetchOccupancyDataHelper.clearAllData(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
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/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_tab/analytics_tab_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_page_tabs_and_children.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_page_tabs_and_children.dart';
|
||||||
@ -11,6 +12,9 @@ import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/real
|
|||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/fake_energy_consumption_by_phases_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/fake_energy_consumption_by_phases_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/fake_energy_consumption_per_device_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/fake_energy_consumption_per_device_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/occupacy/fake_occupacy_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/occupacy/fake_occupacy_service.dart';
|
||||||
@ -23,9 +27,22 @@ import 'package:syncrow_web/services/api/http_service.dart';
|
|||||||
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
|
|
||||||
class AnalyticsPage extends StatelessWidget {
|
class AnalyticsPage extends StatefulWidget {
|
||||||
const AnalyticsPage({super.key});
|
const AnalyticsPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AnalyticsPage> createState() => _AnalyticsPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AnalyticsPageState extends State<AnalyticsPage> {
|
||||||
|
late final HTTPService _httpService;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_httpService = HTTPService();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
@ -35,7 +52,7 @@ class AnalyticsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => TotalEnergyConsumptionBloc(
|
create: (context) => TotalEnergyConsumptionBloc(
|
||||||
RemoteTotalEnergyConsumptionService(HTTPService()),
|
RemoteTotalEnergyConsumptionService(_httpService),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
@ -50,7 +67,7 @@ class AnalyticsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => PowerClampInfoBloc(
|
create: (context) => PowerClampInfoBloc(
|
||||||
RemotePowerClampInfoService(HTTPService()),
|
RemotePowerClampInfoService(_httpService),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlocProvider<RealtimeDeviceChangesBloc>(
|
BlocProvider<RealtimeDeviceChangesBloc>(
|
||||||
@ -61,10 +78,18 @@ class AnalyticsPage extends StatelessWidget {
|
|||||||
BlocProvider(create: (context) => OccupancyBloc(FakeOccupacyService())),
|
BlocProvider(create: (context) => OccupancyBloc(FakeOccupacyService())),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => OccupancyHeatMapBloc(
|
create: (context) => OccupancyHeatMapBloc(
|
||||||
RemoteOccupancyHeatMapService(HTTPService()),
|
RemoteOccupancyHeatMapService(_httpService),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
BlocProvider(create: (context) => AnalyticsDatePickerBloc()),
|
BlocProvider(create: (context) => AnalyticsDatePickerBloc()),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => AnalyticsDevicesBloc(
|
||||||
|
AnalyticsDevicesServiceDelegate(
|
||||||
|
RemoteOccupancyAnalyticsDevicesService(_httpService),
|
||||||
|
RemoteEnergyManagementAnalyticsDevicesService(_httpService),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: const AnalyticsPageForm(),
|
child: const AnalyticsPageForm(),
|
||||||
);
|
);
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
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/analytics/models/analytics_device.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_per_device_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_param.dart';
|
||||||
@ -13,7 +16,10 @@ import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_
|
|||||||
abstract final class FetchEnergyManagementDataHelper {
|
abstract final class FetchEnergyManagementDataHelper {
|
||||||
const FetchEnergyManagementDataHelper._();
|
const FetchEnergyManagementDataHelper._();
|
||||||
|
|
||||||
static const String _powerClampId = 'cb71d6ad-6e29-4eaa-ae3e-1a0d1c5f60fa';
|
// static const String _powerClampId = 'cb71d6ad-6e29-4eaa-ae3e-1a0d1c5f60fa';
|
||||||
|
static AnalyticsDevice? getSelectedDevice(BuildContext context) {
|
||||||
|
return context.read<AnalyticsDevicesBloc>().state.selectedDevice;
|
||||||
|
}
|
||||||
|
|
||||||
static void loadEnergyManagementData(
|
static void loadEnergyManagementData(
|
||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
@ -28,16 +34,14 @@ abstract final class FetchEnergyManagementDataHelper {
|
|||||||
|
|
||||||
final datePickerState = context.read<AnalyticsDatePickerBloc>().state;
|
final datePickerState = context.read<AnalyticsDatePickerBloc>().state;
|
||||||
final selectedDate0 = selectedDate ?? datePickerState.monthlyDate;
|
final selectedDate0 = selectedDate ?? datePickerState.monthlyDate;
|
||||||
|
loadAnalyticsDevices(context, communityUuid: communityId, spaceUuid: spaceId);
|
||||||
loadTotalEnergyConsumption(
|
loadTotalEnergyConsumption(
|
||||||
context,
|
context,
|
||||||
selectedDate: selectedDate0,
|
selectedDate: selectedDate0,
|
||||||
communityId: communityId,
|
communityId: communityId,
|
||||||
spaceId: spaceId,
|
spaceId: spaceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
loadEnergyConsumptionByPhases(context, selectedDate: selectedDate);
|
loadEnergyConsumptionByPhases(context, selectedDate: selectedDate);
|
||||||
|
|
||||||
loadEnergyConsumptionPerDevice(context);
|
loadEnergyConsumptionPerDevice(context);
|
||||||
loadRealtimeDeviceChanges(context);
|
loadRealtimeDeviceChanges(context);
|
||||||
loadPowerClampInfo(context);
|
loadPowerClampInfo(context);
|
||||||
@ -80,25 +84,57 @@ abstract final class FetchEnergyManagementDataHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void loadPowerClampInfo(BuildContext context) {
|
static void loadPowerClampInfo(BuildContext context) {
|
||||||
|
final selectedDevice = getSelectedDevice(context);
|
||||||
|
if (selectedDevice case final AnalyticsDevice device) {
|
||||||
context.read<PowerClampInfoBloc>().add(
|
context.read<PowerClampInfoBloc>().add(
|
||||||
const LoadPowerClampInfoEvent(_powerClampId),
|
LoadPowerClampInfoEvent(device.uuid),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadRealtimeDeviceChanges(
|
||||||
|
BuildContext context, {
|
||||||
|
String? deviceUuid,
|
||||||
|
}) {
|
||||||
|
final selectedDevice = getSelectedDevice(context);
|
||||||
|
|
||||||
|
context.read<RealtimeDeviceChangesBloc>().add(
|
||||||
|
RealtimeDeviceChangesStarted(deviceUuid ?? selectedDevice?.uuid ?? ''),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadRealtimeDeviceChanges(BuildContext context) {
|
static void loadAnalyticsDevices(
|
||||||
|
BuildContext context, {
|
||||||
|
required String communityUuid,
|
||||||
|
required String spaceUuid,
|
||||||
|
}) {
|
||||||
|
context.read<AnalyticsDevicesBloc>().add(
|
||||||
|
LoadAnalyticsDevicesEvent(
|
||||||
|
onSuccess: (device) {
|
||||||
|
context.read<PowerClampInfoBloc>().add(
|
||||||
|
LoadPowerClampInfoEvent(device.uuid),
|
||||||
|
);
|
||||||
context.read<RealtimeDeviceChangesBloc>().add(
|
context.read<RealtimeDeviceChangesBloc>().add(
|
||||||
const RealtimeDeviceChangesStarted(_powerClampId),
|
RealtimeDeviceChangesStarted(device.uuid),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
param: GetAnalyticsDevicesParam(
|
||||||
|
communityUuid: communityUuid,
|
||||||
|
spaceUuid: spaceUuid,
|
||||||
|
deviceTypes: ['PC'],
|
||||||
|
requestType: AnalyticsDeviceRequestType.energyManagement,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearAllData(BuildContext context) {
|
static void clearAllData(BuildContext context) {
|
||||||
context.read<RealtimeDeviceChangesBloc>().add(
|
|
||||||
const RealtimeDeviceChangesClosed(),
|
|
||||||
);
|
|
||||||
|
|
||||||
context.read<PowerClampInfoBloc>().add(
|
context.read<PowerClampInfoBloc>().add(
|
||||||
const ClearPowerClampInfoEvent(),
|
const ClearPowerClampInfoEvent(),
|
||||||
);
|
);
|
||||||
|
context.read<RealtimeDeviceChangesBloc>().add(
|
||||||
|
const RealtimeDeviceChangesClosed(),
|
||||||
|
);
|
||||||
|
|
||||||
context.read<EnergyConsumptionPerDeviceBloc>().add(
|
context.read<EnergyConsumptionPerDeviceBloc>().add(
|
||||||
const ClearEnergyConsumptionPerDeviceEvent(),
|
const ClearEnergyConsumptionPerDeviceEvent(),
|
||||||
@ -111,5 +147,6 @@ abstract final class FetchEnergyManagementDataHelper {
|
|||||||
context.read<EnergyConsumptionByPhasesBloc>().add(
|
context.read<EnergyConsumptionByPhasesBloc>().add(
|
||||||
const ClearEnergyConsumptionByPhasesEvent(),
|
const ClearEnergyConsumptionByPhasesEvent(),
|
||||||
);
|
);
|
||||||
|
context.read<AnalyticsDevicesBloc>().add(const ClearAnalyticsDeviceEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
|
class AnalyticsDeviceDropdown extends StatelessWidget {
|
||||||
|
const AnalyticsDeviceDropdown({required this.onChanged, super.key});
|
||||||
|
|
||||||
|
final ValueChanged<AnalyticsDevice> onChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<AnalyticsDevicesBloc, AnalyticsDevicesState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: ColorsManager.greyColor,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Visibility(
|
||||||
|
visible: state.devices.isNotEmpty,
|
||||||
|
replacement: _buildNoDevicesFound(context),
|
||||||
|
child: _buildDevicesDropdown(context, state),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const _defaultPadding = EdgeInsetsDirectional.symmetric(
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildNoDevicesFound(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: _defaultPadding,
|
||||||
|
child: Text(
|
||||||
|
'no devices found',
|
||||||
|
style: _getTextStyle(context),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDevicesDropdown(BuildContext context, AnalyticsDevicesState state) {
|
||||||
|
return DropdownButton<AnalyticsDevice?>(
|
||||||
|
value: state.selectedDevice,
|
||||||
|
isDense: true,
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
dropdownColor: ColorsManager.whiteColors,
|
||||||
|
underline: const SizedBox.shrink(),
|
||||||
|
icon: const RotatedBox(
|
||||||
|
quarterTurns: 1,
|
||||||
|
child: Icon(Icons.chevron_right, size: 16),
|
||||||
|
),
|
||||||
|
style: _getTextStyle(context),
|
||||||
|
padding: _defaultPadding,
|
||||||
|
items: state.devices.map((e) {
|
||||||
|
return DropdownMenuItem(
|
||||||
|
value: e,
|
||||||
|
child: Text(e.name),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value case final AnalyticsDevice device) {
|
||||||
|
context.read<AnalyticsDevicesBloc>().add(
|
||||||
|
SelectAnalyticsDeviceEvent(device),
|
||||||
|
);
|
||||||
|
onChanged.call(device);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextStyle? _getTextStyle(BuildContext context) {
|
||||||
|
return context.textTheme.labelSmall?.copyWith(
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
fontSize: 14,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,55 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
|
|
||||||
class PowerClampEnergyDataDeviceDropdown extends StatelessWidget {
|
|
||||||
const PowerClampEnergyDataDeviceDropdown({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
border: Border.all(
|
|
||||||
color: ColorsManager.greyColor,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: DropdownButton<String>(
|
|
||||||
value: 'Device 1',
|
|
||||||
isDense: true,
|
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
dropdownColor: ColorsManager.whiteColors,
|
|
||||||
underline: const SizedBox.shrink(),
|
|
||||||
icon: const RotatedBox(
|
|
||||||
quarterTurns: 1,
|
|
||||||
child: Icon(Icons.chevron_right, size: 16),
|
|
||||||
),
|
|
||||||
style: context.textTheme.labelSmall?.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
padding: const EdgeInsetsDirectional.symmetric(
|
|
||||||
horizontal: 20,
|
|
||||||
vertical: 2,
|
|
||||||
),
|
|
||||||
items: [
|
|
||||||
for (var i = 1; i < 10; i++)
|
|
||||||
DropdownMenuItem(
|
|
||||||
value: 'Device $i',
|
|
||||||
child: Text(
|
|
||||||
'Device $i',
|
|
||||||
style: context.textTheme.labelSmall?.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
onChanged: (value) {},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,12 @@
|
|||||||
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/analytics/models/power_clamp_energy_status.dart';
|
import 'package:syncrow_web/pages/analytics/models/power_clamp_energy_status.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart_box.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_device_dropdown.dart';
|
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_status_widget.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_status_widget.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/widgets/analytics_error_widget.dart';
|
import 'package:syncrow_web/pages/analytics/widgets/analytics_error_widget.dart';
|
||||||
@ -50,7 +52,8 @@ class PowerClampEnergyDataWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
SelectableText(
|
SelectableText(
|
||||||
state.powerClampModel?.productUuid ?? 'N/A',
|
context.watch<AnalyticsDevicesBloc>().state.selectedDevice?.uuid ??
|
||||||
|
'N/A',
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
color: ColorsManager.blackColor,
|
color: ColorsManager.blackColor,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@ -107,7 +110,7 @@ class PowerClampEnergyDataWidget extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 3,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
alignment: AlignmentDirectional.centerStart,
|
alignment: AlignmentDirectional.centerStart,
|
||||||
@ -122,11 +125,19 @@ class PowerClampEnergyDataWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
const Expanded(
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
child: PowerClampEnergyDataDeviceDropdown(),
|
child: AnalyticsDeviceDropdown(
|
||||||
|
onChanged: (value) {
|
||||||
|
FetchEnergyManagementDataHelper.loadRealtimeDeviceChanges(
|
||||||
|
context,
|
||||||
|
deviceUuid: value.uuid,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
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/analytics/models/analytics_device.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy/occupancy_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy_heat_map/occupancy_heat_map_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_occupancy_heat_map_param.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart';
|
import 'package:syncrow_web/pages/analytics/params/get_occupancy_param.dart';
|
||||||
|
|
||||||
@ -17,10 +20,14 @@ abstract final class FetchOccupancyDataHelper {
|
|||||||
}) {
|
}) {
|
||||||
if (communityId.isEmpty && spaceId.isEmpty) {
|
if (communityId.isEmpty && spaceId.isEmpty) {
|
||||||
clearAllData(context);
|
clearAllData(context);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final datePickerState = context.read<AnalyticsDatePickerBloc>().state;
|
final datePickerState = context.read<AnalyticsDatePickerBloc>().state;
|
||||||
|
|
||||||
|
loadAnalyticsDevices(context, communityUuid: communityId, spaceUuid: spaceId);
|
||||||
|
final selectedDevice = context.read<AnalyticsDevicesBloc>().state.selectedDevice;
|
||||||
|
|
||||||
context.read<OccupancyBloc>().add(
|
context.read<OccupancyBloc>().add(
|
||||||
LoadOccupancyEvent(
|
LoadOccupancyEvent(
|
||||||
GetOccupancyParam(
|
GetOccupancyParam(
|
||||||
@ -41,10 +48,34 @@ abstract final class FetchOccupancyDataHelper {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (selectedDevice case final AnalyticsDevice device) {
|
||||||
context.read<RealtimeDeviceChangesBloc>()
|
context.read<RealtimeDeviceChangesBloc>()
|
||||||
..add(const RealtimeDeviceChangesClosed())
|
..add(const RealtimeDeviceChangesClosed())
|
||||||
..add(
|
..add(
|
||||||
const RealtimeDeviceChangesStarted('14fe6e7e-47af-4a07-ae0a-7c4a26ef8135'),
|
RealtimeDeviceChangesStarted(device.uuid),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadAnalyticsDevices(
|
||||||
|
BuildContext context, {
|
||||||
|
required String communityUuid,
|
||||||
|
required String spaceUuid,
|
||||||
|
}) {
|
||||||
|
context.read<AnalyticsDevicesBloc>().add(
|
||||||
|
LoadAnalyticsDevicesEvent(
|
||||||
|
param: GetAnalyticsDevicesParam(
|
||||||
|
communityUuid: communityUuid,
|
||||||
|
spaceUuid: spaceUuid,
|
||||||
|
deviceTypes: ['WPS', 'CPS'],
|
||||||
|
requestType: AnalyticsDeviceRequestType.occupancy,
|
||||||
|
),
|
||||||
|
onSuccess: (device) {
|
||||||
|
context.read<RealtimeDeviceChangesBloc>()
|
||||||
|
..add(const RealtimeDeviceChangesClosed())
|
||||||
|
..add(RealtimeDeviceChangesStarted(device.uuid));
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,5 +89,9 @@ abstract final class FetchOccupancyDataHelper {
|
|||||||
context.read<RealtimeDeviceChangesBloc>().add(
|
context.read<RealtimeDeviceChangesBloc>().add(
|
||||||
const RealtimeDeviceChangesClosed(),
|
const RealtimeDeviceChangesClosed(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
context.read<AnalyticsDevicesBloc>().add(
|
||||||
|
const ClearAnalyticsDeviceEvent(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
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/analytics/models/power_clamp_energy_status.dart';
|
import 'package:syncrow_web/pages/analytics/models/power_clamp_energy_status.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_device_dropdown.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/analytics_device_dropdown.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_status_widget.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_status_widget.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
|
||||||
|
|
||||||
class OccupancyEndSideBar extends StatelessWidget {
|
class OccupancyEndSideBar extends StatelessWidget {
|
||||||
const OccupancyEndSideBar({super.key});
|
const OccupancyEndSideBar({super.key});
|
||||||
@ -37,7 +38,8 @@ class OccupancyEndSideBar extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
SelectableText(
|
SelectableText(
|
||||||
(const Uuid().v4()),
|
context.watch<AnalyticsDevicesBloc>().state.selectedDevice?.uuid ??
|
||||||
|
'N/A',
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
color: ColorsManager.blackColor,
|
color: ColorsManager.blackColor,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@ -105,7 +107,7 @@ class OccupancyEndSideBar extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 3,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
alignment: AlignmentDirectional.centerStart,
|
alignment: AlignmentDirectional.centerStart,
|
||||||
@ -120,11 +122,18 @@ class OccupancyEndSideBar extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
const Expanded(
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
child: PowerClampEnergyDataDeviceDropdown(),
|
child: AnalyticsDeviceDropdown(
|
||||||
|
onChanged: (value) =>
|
||||||
|
FetchEnergyManagementDataHelper.loadRealtimeDeviceChanges(
|
||||||
|
context,
|
||||||
|
deviceUuid: value.uuid,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
22
lib/pages/analytics/params/get_analytics_devices_param.dart
Normal file
22
lib/pages/analytics/params/get_analytics_devices_param.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
enum AnalyticsDeviceRequestType { energyManagement, occupancy }
|
||||||
|
|
||||||
|
class GetAnalyticsDevicesParam {
|
||||||
|
final String? spaceUuid;
|
||||||
|
final List<String> deviceTypes;
|
||||||
|
final String? communityUuid;
|
||||||
|
final AnalyticsDeviceRequestType requestType;
|
||||||
|
|
||||||
|
const GetAnalyticsDevicesParam({
|
||||||
|
required this.requestType,
|
||||||
|
required this.spaceUuid,
|
||||||
|
required this.deviceTypes,
|
||||||
|
required this.communityUuid,
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return <String, dynamic>{
|
||||||
|
if (spaceUuid != null) 'spaceUuid': spaceUuid,
|
||||||
|
if (communityUuid != null) 'communityUuid': communityUuid,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
|
|
||||||
|
abstract interface class AnalyticsDevicesService {
|
||||||
|
Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param);
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
||||||
|
|
||||||
|
class AnalyticsDevicesServiceDelegate implements AnalyticsDevicesService {
|
||||||
|
const AnalyticsDevicesServiceDelegate(
|
||||||
|
this._occupancyService,
|
||||||
|
this._energyManagementService,
|
||||||
|
);
|
||||||
|
|
||||||
|
final AnalyticsDevicesService _occupancyService;
|
||||||
|
final AnalyticsDevicesService _energyManagementService;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<AnalyticsDevice>> getDevices(
|
||||||
|
GetAnalyticsDevicesParam param,
|
||||||
|
) {
|
||||||
|
return switch (param.requestType) {
|
||||||
|
AnalyticsDeviceRequestType.occupancy => _occupancyService.getDevices(param),
|
||||||
|
AnalyticsDeviceRequestType.energyManagement =>
|
||||||
|
_energyManagementService.getDevices(param),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
||||||
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
|
final class RemoteEnergyManagementAnalyticsDevicesService
|
||||||
|
implements AnalyticsDevicesService {
|
||||||
|
const RemoteEnergyManagementAnalyticsDevicesService(this._httpService);
|
||||||
|
|
||||||
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param) async {
|
||||||
|
try {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: '/devices-space-community/recursive-child',
|
||||||
|
queryParameters: param.toJson()
|
||||||
|
..addAll({'productType': param.deviceTypes.first}),
|
||||||
|
expectedResponseModel: (response) {
|
||||||
|
final json = response as Map<String, dynamic>;
|
||||||
|
final dailyData = json['data'] as List<dynamic>? ?? <dynamic>[];
|
||||||
|
|
||||||
|
final result = dailyData.map(
|
||||||
|
(json) => AnalyticsDevice.fromJson(json as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.toList();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Failed to load total energy consumption: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:syncrow_web/pages/analytics/models/analytics_device.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/params/get_analytics_devices_param.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
|
|
||||||
|
class RemoteOccupancyAnalyticsDevicesService implements AnalyticsDevicesService {
|
||||||
|
const RemoteOccupancyAnalyticsDevicesService(this._httpService);
|
||||||
|
|
||||||
|
final HTTPService _httpService;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<AnalyticsDevice>> getDevices(GetAnalyticsDevicesParam param) async {
|
||||||
|
try {
|
||||||
|
final requests = await Future.wait<List<AnalyticsDevice>>(
|
||||||
|
param.deviceTypes.map((e) {
|
||||||
|
final mappedParam = GetAnalyticsDevicesParam(
|
||||||
|
requestType: AnalyticsDeviceRequestType.occupancy,
|
||||||
|
spaceUuid: param.spaceUuid,
|
||||||
|
deviceTypes: [e],
|
||||||
|
communityUuid: param.communityUuid,
|
||||||
|
);
|
||||||
|
return _makeRequest(mappedParam);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = requests.map((e) => e.first).toList();
|
||||||
|
return result;
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Failed to load total energy consumption: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<AnalyticsDevice>> _makeRequest(GetAnalyticsDevicesParam param) async {
|
||||||
|
try {
|
||||||
|
final projectUuid = await ProjectManager.getProjectUUID();
|
||||||
|
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path:
|
||||||
|
'/projects/$projectUuid/communities/${param.communityUuid}/spaces/${param.spaceUuid}/devices',
|
||||||
|
queryParameters: {
|
||||||
|
'requestType': param.requestType.name,
|
||||||
|
'communityUuid': param.communityUuid,
|
||||||
|
'spaceUuid': param.spaceUuid,
|
||||||
|
'productType': param.deviceTypes.first,
|
||||||
|
},
|
||||||
|
expectedResponseModel: (response) {
|
||||||
|
final json = response as Map<String, dynamic>;
|
||||||
|
final dailyData = json['data'] as List<dynamic>? ?? <dynamic>[];
|
||||||
|
|
||||||
|
final result = dailyData.map(
|
||||||
|
(json) => AnalyticsDevice.fromJson(json as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
return result.toList();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user