mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
preparing for integration, by fetching data when selecting a community.
This commit is contained in:
@ -1,7 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||
|
||||
class AnalyticsCommunitiesSidebar extends StatelessWidget {
|
||||
@ -9,15 +7,28 @@ class AnalyticsCommunitiesSidebar extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: SpaceTreeView(
|
||||
title: const Text('Communities'),
|
||||
shouldDisableDeselectingChildrenOfSelectedParent: true,
|
||||
onSelect: () {
|
||||
context.read<SpaceTreeBloc>().add(const SpaceTreeClearSelectionEvent());
|
||||
},
|
||||
isSide: false,
|
||||
),
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
return Expanded(
|
||||
child: SpaceTreeView(
|
||||
title: const Text('Communities'),
|
||||
shouldDisableDeselectingChildrenOfSelectedParent: true,
|
||||
onSelect: () {
|
||||
/// Necessary to wait for the state to update before fethcing the data.
|
||||
Future.delayed(
|
||||
const Duration(milliseconds: 100),
|
||||
() {
|
||||
if (context.mounted) {
|
||||
FetchEnergyManagementDataHelper.fetchEnergyManagementData(
|
||||
context);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
isSide: false,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class EnergyConsumptionByPhasesBloc
|
||||
this._energyConsumptionByPhasesService,
|
||||
) : super(const EnergyConsumptionByPhasesState()) {
|
||||
on<LoadEnergyConsumptionByPhasesEvent>(_onLoadEnergyConsumptionByPhasesEvent);
|
||||
on<ClearEnergyConsumptionByPhasesEvent>(_onClearEnergyConsumptionByPhasesEvent);
|
||||
}
|
||||
|
||||
final EnergyConsumptionByPhasesService _energyConsumptionByPhasesService;
|
||||
@ -39,4 +40,11 @@ class EnergyConsumptionByPhasesBloc
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onClearEnergyConsumptionByPhasesEvent(
|
||||
ClearEnergyConsumptionByPhasesEvent event,
|
||||
Emitter<EnergyConsumptionByPhasesState> emit,
|
||||
) async {
|
||||
emit(const EnergyConsumptionByPhasesState());
|
||||
}
|
||||
}
|
||||
|
@ -17,3 +17,7 @@ class LoadEnergyConsumptionByPhasesEvent extends EnergyConsumptionByPhasesEvent
|
||||
@override
|
||||
List<Object> get props => [param];
|
||||
}
|
||||
|
||||
final class ClearEnergyConsumptionByPhasesEvent extends EnergyConsumptionByPhasesEvent {
|
||||
const ClearEnergyConsumptionByPhasesEvent();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class EnergyConsumptionPerDeviceBloc
|
||||
this._energyConsumptionPerDeviceService,
|
||||
) : super(const EnergyConsumptionPerDeviceState()) {
|
||||
on<LoadEnergyConsumptionPerDeviceEvent>(_onLoadEnergyConsumptionPerDeviceEvent);
|
||||
on<ClearEnergyConsumptionPerDeviceEvent>(_onClearEnergyConsumptionPerDeviceEvent);
|
||||
}
|
||||
|
||||
final EnergyConsumptionPerDeviceService _energyConsumptionPerDeviceService;
|
||||
@ -39,4 +40,11 @@ class EnergyConsumptionPerDeviceBloc
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onClearEnergyConsumptionPerDeviceEvent(
|
||||
ClearEnergyConsumptionPerDeviceEvent event,
|
||||
Emitter<EnergyConsumptionPerDeviceState> emit,
|
||||
) async {
|
||||
emit(const EnergyConsumptionPerDeviceState());
|
||||
}
|
||||
}
|
||||
|
@ -16,3 +16,8 @@ final class LoadEnergyConsumptionPerDeviceEvent
|
||||
@override
|
||||
List<Object> get props => [param];
|
||||
}
|
||||
|
||||
final class ClearEnergyConsumptionPerDeviceEvent
|
||||
extends EnergyConsumptionPerDeviceEvent {
|
||||
const ClearEnergyConsumptionPerDeviceEvent();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class PowerClampInfoBloc extends Bloc<PowerClampInfoEvent, PowerClampInfoState>
|
||||
) : super(const PowerClampInfoState()) {
|
||||
on<LoadPowerClampInfoEvent>(_onLoadPowerClampInfoEvent);
|
||||
on<UpdatePowerClampStatusEvent>(_onUpdatePowerClampStatusEvent);
|
||||
on<ClearPowerClampInfoEvent>(_onClearPowerClampInfoEvent);
|
||||
}
|
||||
|
||||
final PowerClampInfoService _powerClampInfoService;
|
||||
@ -52,4 +53,11 @@ class PowerClampInfoBloc extends Bloc<PowerClampInfoEvent, PowerClampInfoState>
|
||||
|
||||
emit(state.copyWith(powerClampModel: updatedModel));
|
||||
}
|
||||
|
||||
void _onClearPowerClampInfoEvent(
|
||||
ClearPowerClampInfoEvent event,
|
||||
Emitter<PowerClampInfoState> emit,
|
||||
) {
|
||||
emit(const PowerClampInfoState());
|
||||
}
|
||||
}
|
||||
|
@ -24,4 +24,8 @@ final class UpdatePowerClampStatusEvent extends PowerClampInfoEvent {
|
||||
|
||||
@override
|
||||
List<Object> get props => [statusList];
|
||||
}
|
||||
|
||||
final class ClearPowerClampInfoEvent extends PowerClampInfoEvent {
|
||||
const ClearPowerClampInfoEvent();
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/analytics/services/realtime_device_service/realtime_device_service.dart';
|
||||
@ -12,35 +14,66 @@ class RealtimeDeviceChangesBloc
|
||||
this._realtimeDeviceService,
|
||||
) : super(const RealtimeDeviceChangesState()) {
|
||||
on<RealtimeDeviceChangesStarted>(_onRealtimeDeviceChangesStarted);
|
||||
on<RealtimeDeviceChangesClosed>(_onRealtimeDeviceChangesClosed);
|
||||
on<_RealtimeDeviceChangesUpdated>(_onRealtimeDeviceChangesUpdated);
|
||||
}
|
||||
|
||||
final RealtimeDeviceService _realtimeDeviceService;
|
||||
StreamSubscription<List<Status>>? _subscription;
|
||||
|
||||
Future<void> _onRealtimeDeviceChangesStarted(
|
||||
RealtimeDeviceChangesStarted event,
|
||||
Emitter<RealtimeDeviceChangesState> emit,
|
||||
) async {
|
||||
await emit.onEach(
|
||||
_realtimeDeviceService.subscribe(event.deviceId),
|
||||
onData: (data) {
|
||||
final currentState = state;
|
||||
await _subscription?.cancel();
|
||||
_subscription = _realtimeDeviceService.subscribe(event.deviceId).listen(
|
||||
(data) {
|
||||
add(_RealtimeDeviceChangesUpdated(data));
|
||||
},
|
||||
onError: (error) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: RealtimeDeviceChangesStatus.loaded,
|
||||
deviceStatusList: [
|
||||
...currentState.deviceStatusList.where((device) =>
|
||||
!data.any((newDevice) => newDevice.code == device.code)),
|
||||
...data,
|
||||
],
|
||||
status: RealtimeDeviceChangesStatus.failure,
|
||||
errorMessage: '$error',
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (error, _) => emit(
|
||||
state.copyWith(
|
||||
status: RealtimeDeviceChangesStatus.failure,
|
||||
errorMessage: '$error',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onRealtimeDeviceChangesClosed(
|
||||
RealtimeDeviceChangesClosed event,
|
||||
Emitter<RealtimeDeviceChangesState> emit,
|
||||
) async {
|
||||
await _subscription?.cancel();
|
||||
_subscription = null;
|
||||
emit(state.copyWith(status: RealtimeDeviceChangesStatus.closed));
|
||||
}
|
||||
|
||||
void _onRealtimeDeviceChangesUpdated(
|
||||
_RealtimeDeviceChangesUpdated event,
|
||||
Emitter<RealtimeDeviceChangesState> emit,
|
||||
) {
|
||||
final currentState = state;
|
||||
final updatedList = [
|
||||
...currentState.deviceStatusList.where(
|
||||
(device) => !event.deviceStatusList
|
||||
.any((newDevice) => newDevice.code == device.code),
|
||||
),
|
||||
...event.deviceStatusList,
|
||||
];
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: RealtimeDeviceChangesStatus.loaded,
|
||||
deviceStatusList: updatedList,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_subscription?.cancel();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
@ -15,3 +15,13 @@ final class RealtimeDeviceChangesStarted extends RealtimeDeviceChangesEvent {
|
||||
@override
|
||||
List<Object> get props => [deviceId];
|
||||
}
|
||||
|
||||
final class RealtimeDeviceChangesClosed extends RealtimeDeviceChangesEvent {
|
||||
const RealtimeDeviceChangesClosed();
|
||||
}
|
||||
|
||||
class _RealtimeDeviceChangesUpdated extends RealtimeDeviceChangesEvent {
|
||||
final List<Status> deviceStatusList;
|
||||
|
||||
const _RealtimeDeviceChangesUpdated(this.deviceStatusList);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
part of 'realtime_device_changes_bloc.dart';
|
||||
|
||||
enum RealtimeDeviceChangesStatus { initial, loaded, failure }
|
||||
enum RealtimeDeviceChangesStatus { initial, loaded, failure, closed }
|
||||
|
||||
final class RealtimeDeviceChangesState extends Equatable {
|
||||
const RealtimeDeviceChangesState({
|
||||
|
@ -13,6 +13,7 @@ class TotalEnergyConsumptionBloc
|
||||
this._totalEnergyConsumptionService,
|
||||
) : super(const TotalEnergyConsumptionState()) {
|
||||
on<TotalEnergyConsumptionLoadEvent>(_onTotalEnergyConsumptionLoadEvent);
|
||||
on<ClearTotalEnergyConsumptionEvent>(_onClearTotalEnergyConsumptionEvent);
|
||||
}
|
||||
|
||||
final TotalEnergyConsumptionService _totalEnergyConsumptionService;
|
||||
@ -39,4 +40,11 @@ class TotalEnergyConsumptionBloc
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onClearTotalEnergyConsumptionEvent(
|
||||
ClearTotalEnergyConsumptionEvent event,
|
||||
Emitter<TotalEnergyConsumptionState> emit,
|
||||
) async {
|
||||
emit(const TotalEnergyConsumptionState());
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,12 @@ sealed class TotalEnergyConsumptionEvent extends Equatable {
|
||||
final class TotalEnergyConsumptionLoadEvent extends TotalEnergyConsumptionEvent {
|
||||
const TotalEnergyConsumptionLoadEvent({required this.param});
|
||||
|
||||
final GetTotalEnergyConsumptionParam param ;
|
||||
final GetTotalEnergyConsumptionParam param;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [param];
|
||||
}
|
||||
|
||||
final class ClearTotalEnergyConsumptionEvent extends TotalEnergyConsumptionEvent {
|
||||
const ClearTotalEnergyConsumptionEvent();
|
||||
}
|
||||
|
@ -0,0 +1,100 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_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/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/total_energy_consumption/total_energy_consumption_bloc.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_total_energy_consumption_param.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
|
||||
abstract final class FetchEnergyManagementDataHelper {
|
||||
const FetchEnergyManagementDataHelper._();
|
||||
|
||||
static void fetchEnergyManagementData(BuildContext context) {
|
||||
final (selectedCommunities, selectedSpaces) =
|
||||
_getSelectedCommunitiesAndSpaces(context);
|
||||
|
||||
if (selectedCommunities.isEmpty && selectedSpaces.isEmpty) {
|
||||
clearAllData(context);
|
||||
return;
|
||||
}
|
||||
|
||||
loadTotalEnergyConsumption(context);
|
||||
loadEnergyConsumptionByPhases(context);
|
||||
loadPowerClampInfo(context);
|
||||
loadEnergyConsumptionPerDevice(context);
|
||||
loadRealtimeDeviceChanges(context);
|
||||
return;
|
||||
}
|
||||
|
||||
static (List<String> selectedCommunities, List<String> selectedSpaces)
|
||||
_getSelectedCommunitiesAndSpaces(BuildContext context) {
|
||||
final spaceTreeState = context.read<SpaceTreeBloc>().state;
|
||||
final selectedCommunities = spaceTreeState.selectedCommunities;
|
||||
final selectedSpaces = spaceTreeState.selectedSpaces;
|
||||
|
||||
return (selectedCommunities, selectedSpaces);
|
||||
}
|
||||
|
||||
static void loadEnergyConsumptionByPhases(BuildContext context) {
|
||||
const param = GetEnergyConsumptionByPhasesParam();
|
||||
context.read<EnergyConsumptionByPhasesBloc>().add(
|
||||
const LoadEnergyConsumptionByPhasesEvent(param: param),
|
||||
);
|
||||
}
|
||||
|
||||
static void loadTotalEnergyConsumption(BuildContext context) {
|
||||
final (selectedCommunities, selectedSpaces) =
|
||||
_getSelectedCommunitiesAndSpaces(context);
|
||||
|
||||
final param = GetTotalEnergyConsumptionParam(
|
||||
spaceId: selectedCommunities.firstOrNull,
|
||||
);
|
||||
context.read<TotalEnergyConsumptionBloc>().add(
|
||||
TotalEnergyConsumptionLoadEvent(param: param),
|
||||
);
|
||||
}
|
||||
|
||||
static void loadEnergyConsumptionPerDevice(BuildContext context) {
|
||||
const param = GetEnergyConsumptionPerDeviceParam();
|
||||
context.read<EnergyConsumptionPerDeviceBloc>().add(
|
||||
const LoadEnergyConsumptionPerDeviceEvent(param),
|
||||
);
|
||||
}
|
||||
|
||||
static void loadPowerClampInfo(BuildContext context) {
|
||||
context.read<PowerClampInfoBloc>().add(
|
||||
const LoadPowerClampInfoEvent('cb71d6ad-6e29-4eaa-ae3e-1a0d1c5f60fa'),
|
||||
);
|
||||
}
|
||||
|
||||
static void loadRealtimeDeviceChanges(BuildContext context) {
|
||||
context.read<RealtimeDeviceChangesBloc>().add(
|
||||
const RealtimeDeviceChangesStarted('cb71d6ad-6e29-4eaa-ae3e-1a0d1c5f60fa'),
|
||||
);
|
||||
}
|
||||
|
||||
static void clearAllData(BuildContext context) {
|
||||
context.read<RealtimeDeviceChangesBloc>().add(
|
||||
const RealtimeDeviceChangesClosed(),
|
||||
);
|
||||
|
||||
context.read<PowerClampInfoBloc>().add(
|
||||
const ClearPowerClampInfoEvent(),
|
||||
);
|
||||
context.read<EnergyConsumptionPerDeviceBloc>().add(
|
||||
const ClearEnergyConsumptionPerDeviceEvent(),
|
||||
);
|
||||
|
||||
context.read<TotalEnergyConsumptionBloc>().add(
|
||||
const ClearTotalEnergyConsumptionEvent(),
|
||||
);
|
||||
|
||||
context.read<EnergyConsumptionByPhasesBloc>().add(
|
||||
const ClearEnergyConsumptionByPhasesEvent(),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,70 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_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/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/total_energy_consumption/total_energy_consumption_bloc.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart_box.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_total_energy_consumption_param.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class AnalyticsEnergyManagementView extends StatefulWidget {
|
||||
class AnalyticsEnergyManagementView extends StatelessWidget {
|
||||
const AnalyticsEnergyManagementView({super.key});
|
||||
|
||||
@override
|
||||
State<AnalyticsEnergyManagementView> createState() =>
|
||||
_AnalyticsEnergyManagementViewState();
|
||||
}
|
||||
|
||||
class _AnalyticsEnergyManagementViewState
|
||||
extends State<AnalyticsEnergyManagementView> {
|
||||
@override
|
||||
void initState() {
|
||||
_loadEnergyConsumptionByPhases();
|
||||
_loadTotalEnergyConsumption();
|
||||
_loadEnergyConsumptionPerDevice();
|
||||
_loadPowerClampInfo();
|
||||
|
||||
context.read<RealtimeDeviceChangesBloc>().add(
|
||||
const RealtimeDeviceChangesStarted(
|
||||
'cb71d6ad-6e29-4eaa-ae3e-1a0d1c5f60fa',
|
||||
),
|
||||
);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void _loadEnergyConsumptionByPhases() {
|
||||
const param = GetEnergyConsumptionByPhasesParam();
|
||||
context.read<EnergyConsumptionByPhasesBloc>().add(
|
||||
const LoadEnergyConsumptionByPhasesEvent(param: param),
|
||||
);
|
||||
}
|
||||
|
||||
void _loadTotalEnergyConsumption() {
|
||||
const param = GetTotalEnergyConsumptionParam();
|
||||
context.read<TotalEnergyConsumptionBloc>().add(
|
||||
const TotalEnergyConsumptionLoadEvent(param: param),
|
||||
);
|
||||
}
|
||||
|
||||
void _loadEnergyConsumptionPerDevice() {
|
||||
const param = GetEnergyConsumptionPerDeviceParam();
|
||||
context.read<EnergyConsumptionPerDeviceBloc>().add(
|
||||
const LoadEnergyConsumptionPerDeviceEvent(param),
|
||||
);
|
||||
}
|
||||
|
||||
void _loadPowerClampInfo() {
|
||||
context.read<PowerClampInfoBloc>().add(
|
||||
const LoadPowerClampInfoEvent('deviceId'),
|
||||
);
|
||||
}
|
||||
|
||||
static const _padding = EdgeInsetsDirectional.all(32);
|
||||
|
||||
@override
|
||||
@ -80,13 +21,7 @@ class _AnalyticsEnergyManagementViewState
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.sizeOf(context).height * 1.2,
|
||||
child: Container(
|
||||
decoration: subSectionContainerDecoration.copyWith(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
padding: const EdgeInsetsDirectional.all(32),
|
||||
child: const PowerClampEnergyDataWidget(),
|
||||
),
|
||||
child: const PowerClampEnergyDataWidget(),
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.sizeOf(context).height * 0.5,
|
||||
|
Reference in New Issue
Block a user