Merge branch 'dev' of https://github.com/SyncrowIOT/web into SP-1665-FE-Return-a-readable-error-when-a-connection-error-Exception-occurs-on-the-charts

This commit is contained in:
Faris Armoush
2025-06-04 14:49:48 +03:00
38 changed files with 1720 additions and 169 deletions
@@ -23,17 +23,18 @@ class AnalyticsDevice {
return AnalyticsDevice(
uuid: json['uuid'] as String,
name: json['name'] as String,
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt'] as String) : null,
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt'] as String) : null,
createdAt: json['createdAt'] != null
? DateTime.parse(json['createdAt'] as String)
: null,
updatedAt: json['updatedAt'] != null
? DateTime.parse(json['updatedAt'] as String)
: null,
deviceTuyaUuid: json['deviceTuyaUuid'] as String?,
isActive: json['isActive'] as bool?,
productDevice: json['productDevice'] != null
? ProductDevice.fromJson(json['productDevice'] as Map<String, dynamic>)
: null,
spaceUuid: (json['spaces'] as List<dynamic>?)
?.map((e) => e['uuid'])
.firstOrNull
?.toString(),
productDevice: json['productDevice'] != null
? ProductDevice.fromJson(json['productDevice'] as Map<String, dynamic>)
: null,
spaceUuid: json['spaceUuid'] as String?,
);
}
}
@@ -60,8 +61,12 @@ class ProductDevice {
factory ProductDevice.fromJson(Map<String, dynamic> json) {
return ProductDevice(
uuid: json['uuid'] as String?,
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt'] as String) : null,
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt'] as String) : null,
createdAt: json['createdAt'] != null
? DateTime.parse(json['createdAt'] as String)
: null,
updatedAt: json['updatedAt'] != null
? DateTime.parse(json['updatedAt'] as String)
: null,
catName: json['catName'] as String?,
prodId: json['prodId'] as String?,
name: json['name'] as String?,
@@ -38,7 +38,7 @@ abstract final class EnergyManagementChartsHelper {
sideTitles: SideTitles(
showTitles: true,
maxIncluded: false,
minIncluded: false,
minIncluded: true,
interval: leftTitlesInterval,
reservedSize: 110,
getTitlesWidget: (value, meta) => Padding(
@@ -16,7 +16,6 @@ import 'package:syncrow_web/pages/analytics/params/get_total_energy_consumption_
abstract final class FetchEnergyManagementDataHelper {
const FetchEnergyManagementDataHelper._();
// static const String _powerClampId = 'cb71d6ad-6e29-4eaa-ae3e-1a0d1c5f60fa';
static AnalyticsDevice? getSelectedDevice(BuildContext context) {
return context.read<AnalyticsDevicesBloc>().state.selectedDevice;
}
@@ -48,7 +47,6 @@ abstract final class FetchEnergyManagementDataHelper {
loadTotalEnergyConsumption(
context,
selectedDate: selectedDate0,
communityId: communityId,
spaceId: spaceId,
);
final selectedDevice = getSelectedDevice(context);
@@ -61,7 +59,6 @@ abstract final class FetchEnergyManagementDataHelper {
}
loadEnergyConsumptionPerDevice(
context,
communityId: communityId,
spaceId: spaceId,
selectedDate: selectedDate0,
);
@@ -84,12 +81,10 @@ abstract final class FetchEnergyManagementDataHelper {
static void loadTotalEnergyConsumption(
BuildContext context, {
DateTime? selectedDate,
required String communityId,
required String spaceId,
}) {
final param = GetTotalEnergyConsumptionParam(
spaceId: spaceId,
communityId: communityId,
monthDate: selectedDate,
);
context.read<TotalEnergyConsumptionBloc>().add(
@@ -100,12 +95,10 @@ abstract final class FetchEnergyManagementDataHelper {
static void loadEnergyConsumptionPerDevice(
BuildContext context, {
DateTime? selectedDate,
required String communityId,
required String spaceId,
}) {
final param = GetEnergyConsumptionPerDeviceParam(
spaceId: spaceId,
communityId: communityId,
monthDate: selectedDate,
);
context.read<EnergyConsumptionPerDeviceBloc>().add(
@@ -23,7 +23,6 @@ class EnergyConsumptionPerDeviceChartBox extends StatelessWidget {
),
padding: const EdgeInsets.all(30),
child: Column(
spacing: 20,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AnalyticsErrorWidget(state.errorMessage),
@@ -52,7 +51,9 @@ class EnergyConsumptionPerDeviceChartBox extends StatelessWidget {
),
],
),
const SizedBox(height: 20),
const Divider(height: 0),
const SizedBox(height: 20),
Expanded(
child: EnergyConsumptionPerDeviceChart(chartData: state.chartData),
),
@@ -41,7 +41,7 @@ class EnergyConsumptionPerDeviceDevicesList extends StatelessWidget {
.color;
return Tooltip(
message: '${device.name}\n${device.productDevice?.uuid ?? ''}',
message: '${device.name}\n${device.spaceUuid ?? ''}',
child: ChartInformativeCell(title: Text(device.name), color: deviceColor),
);
}
@@ -41,7 +41,7 @@ class PowerClampEnergyDataWidget extends StatelessWidget {
AnalyticsErrorWidget(state.errorMessage),
AnalyticsSidebarHeader(
title: 'Smart Power Clamp',
showSpaceUuid: true,
showSpaceUuidInDevicesDropdown: true,
onChanged: (device) {
FetchEnergyManagementDataHelper.loadEnergyConsumptionByPhases(
context,
@@ -19,7 +19,6 @@ class TotalEnergyConsumptionChartBox extends StatelessWidget {
),
padding: const EdgeInsets.all(30),
child: Column(
spacing: 20,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AnalyticsErrorWidget(state.errorMessage),
@@ -39,7 +38,9 @@ class TotalEnergyConsumptionChartBox extends StatelessWidget {
const Spacer(flex: 4),
],
),
const SizedBox(height: 20),
const Divider(),
const SizedBox(height: 20),
TotalEnergyConsumptionChart(chartData: state.chartData),
],
),
@@ -16,7 +16,7 @@ class OccupancyChart extends StatelessWidget {
Widget build(BuildContext context) {
return BarChart(
BarChartData(
maxY: 100.0,
maxY: 100.001,
gridData: EnergyManagementChartsHelper.gridData().copyWith(
checkToShowHorizontalLine: (value) => true,
horizontalInterval: 20,
@@ -134,7 +134,7 @@ class OccupancyChart extends StatelessWidget {
alignment: AlignmentDirectional.bottomCenter,
fit: BoxFit.scaleDown,
child: Text(
(value + 1).toString(),
chartData[value.toInt()].date.day.toString(),
style: context.textTheme.bodySmall?.copyWith(
color: ColorsManager.greyColor,
fontSize: 8,
@@ -22,7 +22,6 @@ class OccupancyChartBox extends StatelessWidget {
padding: const EdgeInsets.all(30),
decoration: containerWhiteDecoration,
child: Column(
spacing: 20,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -65,7 +64,9 @@ class OccupancyChartBox extends StatelessWidget {
),
],
),
const Divider(height: 0),
const SizedBox(height: 20),
const Divider(),
const SizedBox(height: 20),
Expanded(child: OccupancyChart(chartData: state.chartData)),
],
),
@@ -22,7 +22,6 @@ class OccupancyHeatMapBox extends StatelessWidget {
padding: const EdgeInsets.all(30),
decoration: containerWhiteDecoration,
child: Column(
spacing: 20,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -66,7 +65,9 @@ class OccupancyHeatMapBox extends StatelessWidget {
),
],
),
const Divider(height: 0),
const SizedBox(height: 20),
const Divider(),
const SizedBox(height: 20),
Expanded(
child: OccupancyHeatMap(
heatMapData: state.heatMapData.asMap().map(
@@ -2,18 +2,15 @@ class GetEnergyConsumptionPerDeviceParam {
const GetEnergyConsumptionPerDeviceParam({
this.monthDate,
this.spaceId,
this.communityId,
});
final DateTime? monthDate;
final String? spaceId;
final String? communityId;
Map<String, dynamic> toJson() => {
'monthDate':
'${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}',
if (spaceId == null || spaceId == null) 'spaceUuid': spaceId,
'communityUuid': communityId,
'groupByDevice': true,
};
}
@@ -1,12 +1,10 @@
class GetTotalEnergyConsumptionParam {
final DateTime? monthDate;
final String? spaceId;
final String? communityId;
const GetTotalEnergyConsumptionParam({
this.monthDate,
this.spaceId,
this.communityId,
});
Map<String, dynamic> toJson() {
@@ -14,7 +12,6 @@ class GetTotalEnergyConsumptionParam {
'monthDate':
'${monthDate?.year}-${monthDate?.month.toString().padLeft(2, '0')}',
if (spaceId == null || spaceId == null) 'spaceUuid': spaceId,
'communityUuid': communityId,
'groupByDevice': false,
};
}
@@ -11,14 +11,17 @@ class AnalyticsErrorWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Visibility(
visible: errorMessage != null || (errorMessage?.isNotEmpty ?? false),
child: Text(
errorMessage ?? 'Something went wrong',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.textTheme.bodySmall?.copyWith(
color: ColorsManager.red,
fontWeight: FontWeight.w400,
fontSize: 8,
child: Padding(
padding: const EdgeInsetsDirectional.only(bottom: 10),
child: Text(
errorMessage ?? 'Something went wrong',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.textTheme.bodySmall?.copyWith(
color: ColorsManager.red,
fontWeight: FontWeight.w400,
fontSize: 8,
),
),
),
);
@@ -10,13 +10,13 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart';
class AnalyticsSidebarHeader extends StatelessWidget {
const AnalyticsSidebarHeader({
required this.title,
this.showSpaceUuid = false,
this.showSpaceUuidInDevicesDropdown = false,
this.onChanged,
super.key,
});
final String title;
final bool showSpaceUuid;
final bool showSpaceUuidInDevicesDropdown;
final void Function(AnalyticsDevice device)? onChanged;
@override
@@ -49,6 +49,7 @@ class AnalyticsSidebarHeader extends StatelessWidget {
alignment: AlignmentDirectional.centerEnd,
fit: BoxFit.scaleDown,
child: AnalyticsDeviceDropdown(
showSpaceUuid: showSpaceUuidInDevicesDropdown,
onChanged: (value) {
context.read<AnalyticsDevicesBloc>().add(
SelectAnalyticsDeviceEvent(value),