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 new file mode 100644 index 00000000..dc2386de --- /dev/null +++ b/lib/pages/device_managment/all_devices/models/device_subspace.model.dart @@ -0,0 +1,47 @@ +class DeviceSubspace { + final String uuid; + final DateTime? createdAt; + final DateTime? updatedAt; + final String subspaceName; + final bool disabled; + + DeviceSubspace({ + required this.uuid, + this.createdAt, + this.updatedAt, + required this.subspaceName, + required this.disabled, + }); + + factory DeviceSubspace.fromJson(Map json) { + return DeviceSubspace( + uuid: json['uuid'] as String, + createdAt: json['createdAt'] != null + ? DateTime.tryParse(json['createdAt'].toString()) + : null, + updatedAt: json['updatedAt'] != null + ? DateTime.tryParse(json['updatedAt'].toString()) + : null, + subspaceName: json['subspaceName'] as String, + disabled: json['disabled'] as bool, + ); + } + + Map toJson() { + return { + 'uuid': uuid, + 'createdAt': createdAt?.toIso8601String(), + 'updatedAt': updatedAt?.toIso8601String(), + 'subspaceName': subspaceName, + 'disabled': disabled, + }; + } + + static List listFromJson(List jsonList) { + return jsonList.map((json) => DeviceSubspace.fromJson(json)).toList(); + } + + static List> listToJson(List subspaces) { + return subspaces.map((subspace) => subspace.toJson()).toList(); + } +} diff --git a/lib/pages/device_managment/all_devices/models/devices_model.dart b/lib/pages/device_managment/all_devices/models/devices_model.dart index b7e4f010..576e895f 100644 --- a/lib/pages/device_managment/all_devices/models/devices_model.dart +++ b/lib/pages/device_managment/all_devices/models/devices_model.dart @@ -1,5 +1,6 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_community.model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_space_model.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_subspace.model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart'; import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart'; @@ -47,6 +48,7 @@ class AllDevicesModel { */ DevicesModelRoom? room; + DeviceSubspace? subspace; DevicesModelUnit? unit; DeviceCommunityModel? community; String? productUuid; @@ -77,6 +79,7 @@ class AllDevicesModel { AllDevicesModel({ this.room, + this.subspace, this.unit, this.community, this.productUuid, @@ -110,6 +113,9 @@ class AllDevicesModel { room = (json['room'] != null && (json['room'] is Map)) ? DevicesModelRoom.fromJson(json['room']) : null; + subspace = (json['subspace'] != null && (json['subspace'] is Map)) + ? DeviceSubspace.fromJson(json['subspace']) + : null; unit = (json['unit'] != null && (json['unit'] is Map)) ? DevicesModelUnit.fromJson(json['unit']) : null; @@ -288,6 +294,9 @@ SOS if (room != null) { data['room'] = room!.toJson(); } + if (subspace != null) { + data['subspace'] = subspace!.toJson(); + } if (unit != null) { data['unit'] = unit!.toJson(); } @@ -330,6 +339,7 @@ SOS return other is AllDevicesModel && other.room == room && + other.subspace == subspace && other.unit == unit && other.productUuid == productUuid && other.productType == productType && @@ -360,6 +370,7 @@ SOS @override int get hashCode { return room.hashCode ^ + subspace.hashCode ^ unit.hashCode ^ productUuid.hashCode ^ productType.hashCode ^ diff --git a/lib/pages/device_managment/shared/device_control_dialog.dart b/lib/pages/device_managment/shared/device_control_dialog.dart index aa1153af..7304dd07 100644 --- a/lib/pages/device_managment/shared/device_control_dialog.dart +++ b/lib/pages/device_managment/shared/device_control_dialog.dart @@ -95,8 +95,9 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { ]), TableRow( children: [ - _buildInfoRow('Space Name:', device.unit?.name ?? 'N/A'), - _buildInfoRow('Room:', device.room?.name ?? 'N/A'), + _buildInfoRow('Space Name:', + device.spaces?.firstOrNull?.spaceName ?? 'N/A'), + _buildInfoRow('Room:', device.subspace?.subspaceName ?? 'N/A'), ], ), TableRow( @@ -111,9 +112,13 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode { ), _buildInfoRow( 'Battery Level:', - device.batteryLevel != null ? '${device.batteryLevel ?? 0}%' : "-", + device.batteryLevel != null + ? '${device.batteryLevel ?? 0}%' + : "-", statusColor: device.batteryLevel != null - ? (device.batteryLevel! < 20 ? ColorsManager.red : ColorsManager.green) + ? (device.batteryLevel! < 20 + ? ColorsManager.red + : ColorsManager.green) : null, ), ], diff --git a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart index 2c86523f..a89ec409 100644 --- a/lib/pages/spaces_management/all_spaces/model/subspace_model.dart +++ b/lib/pages/spaces_management/all_spaces/model/subspace_model.dart @@ -1,5 +1,6 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/utils/constants/action_enum.dart'; +import 'package:uuid/uuid.dart'; import 'tag.dart'; @@ -8,19 +9,24 @@ class SubspaceModel { String subspaceName; final bool disabled; List? tags; + String internalId; SubspaceModel({ this.uuid, required this.subspaceName, required this.disabled, this.tags, - }); + String? internalId, + }) : internalId = internalId ?? const Uuid().v4(); factory SubspaceModel.fromJson(Map json) { + final String internalId = json['internalId'] ?? const Uuid().v4(); + return SubspaceModel( uuid: json['uuid'] ?? '', subspaceName: json['subspaceName'] ?? '', disabled: json['disabled'] ?? false, + internalId: internalId, tags: (json['tags'] as List?) ?.map((item) => Tag.fromJson(item)) .toList() ?? @@ -43,7 +49,7 @@ class UpdateSubspaceModel { final Action action; final String? subspaceName; final List? tags; - UpdateSubspaceModel({ + UpdateSubspaceModel({ required this.action, required this.uuid, this.subspaceName, @@ -107,4 +113,4 @@ class UpdateTag { 'product': product?.toMap(), }; } -} \ No newline at end of file +} diff --git a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart index 405ccd92..ada60850 100644 --- a/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart +++ b/lib/pages/spaces_management/all_spaces/widgets/dialogs/create_space_dialog.dart @@ -358,10 +358,21 @@ class CreateSpaceDialogState extends State { SubspaceNameDisplayWidget( text: subspace.subspaceName, validateName: (updatedName) { - return subspaces!.any((s) => - s != subspace && - s.subspaceName == - updatedName); + bool nameExists = + subspaces!.any((s) { + bool isSameId = s.internalId == + subspace.internalId; + bool isSameName = s.subspaceName + .trim() + .toLowerCase() == + updatedName + .trim() + .toLowerCase(); + + return !isSameId && isSameName; + }); + + return !nameExists; }, onNameChanged: (updatedName) { setState(() {