From fb6952e10e243d0e6521e79c211c0124c3d2b7bf Mon Sep 17 00:00:00 2001 From: Vladimir Vuckovic Date: Fri, 4 Oct 2024 12:08:35 +0200 Subject: [PATCH 1/4] feat: add Identity device table --- .../identity_details/identity_details.dart | 3 + .../identity_devices/identity_devices.dart | 70 +++++++++++++++++++ .../AdminUi/apps/admin_ui/lib/l10n/app_en.arb | 4 ++ .../lib/src/identities/identity_device.dart | 2 + .../lib/src/identities/identity_device.g.dart | 2 + 5 files changed, 81 insertions(+) create mode 100644 Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart diff --git a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_details.dart b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_details.dart index cd5af44fc4..4280972438 100644 --- a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_details.dart +++ b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_details.dart @@ -7,6 +7,7 @@ import 'package:intl/intl.dart'; import '/core/core.dart'; import 'deletion_process_table/deletion_process_table.dart'; +import 'identity_devices/identity_devices.dart'; import 'identity_messages/identity_messages.dart'; import 'identity_quotas/identity_quotas.dart'; import 'identity_relationships/identity_relationships.dart'; @@ -84,6 +85,8 @@ class _IdentityDetailsState extends State { Gaps.h16, IdentityQuotas(identityDetails, _reloadIdentity), Gaps.h16, + IdentityDevices(devices: identityDetails.devices), + Gaps.h16, IdentityRelationships(address: identityDetails.address), Gaps.h16, IdentityMessages( diff --git a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart new file mode 100644 index 0000000000..989e1aa869 --- /dev/null +++ b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart @@ -0,0 +1,70 @@ +import 'package:admin_api_types/admin_api_types.dart'; +import 'package:data_table_2/data_table_2.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '/core/core.dart'; + +class IdentityDevices extends StatelessWidget { + final List devices; + + const IdentityDevices({required this.devices, super.key}); + + @override + Widget build(BuildContext context) { + return Theme( + data: Theme.of(context).copyWith(dividerColor: Colors.transparent), + child: ExpansionTile( + title: Text(context.l10n.identityDevices_title), + subtitle: Text(context.l10n.identityDevices_title_description), + children: [ + Card( + child: Column( + children: [ + SizedBox( + width: double.infinity, + height: 500, + child: DataTable2( + empty: Text(context.l10n.deletionProcessTable_noDeletionProcessFound), + columns: [ + DataColumn2(label: Text(context.l10n.id)), + DataColumn2(label: Text(context.l10n.identityDevices_username)), + DataColumn2(label: Text(context.l10n.createdAt)), + DataColumn2(label: Text(context.l10n.lastLoginAt)), + DataColumn2(label: Text(context.l10n.identityDevices_communicationLanguage)), + ], + rows: devices.map( + (device) { + final textColor = Theme.of(context).colorScheme.onSecondaryContainer; + + return DataRow2( + cells: [ + DataCell(Text(device.id, style: TextStyle(color: textColor))), + DataCell(Text(device.username, style: TextStyle(color: textColor))), + DataCell( + Text( + DateFormat.yMd(Localizations.localeOf(context).languageCode).format(device.createdAt), + style: TextStyle(color: textColor), + ), + ), + DataCell( + Text( + device.lastLogin!.isEmpty ? '${device.lastLogin!.entries.first}' : '-', + style: TextStyle(color: textColor), + ), + ), + DataCell(Text(device.communicationLanguage, style: TextStyle(color: textColor))), + ], + ); + }, + ).toList(), + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/Applications/AdminUi/apps/admin_ui/lib/l10n/app_en.arb b/Applications/AdminUi/apps/admin_ui/lib/l10n/app_en.arb index 3cd9240b1d..d9494b14e2 100644 --- a/Applications/AdminUi/apps/admin_ui/lib/l10n/app_en.arb +++ b/Applications/AdminUi/apps/admin_ui/lib/l10n/app_en.arb @@ -142,6 +142,10 @@ "identityDetails_sentMessages_title": "Sent Messages", "identityDetails_sentMessages_subtitle": "View messages sent by this identity.", "identityDetails_noSentMessagesFound": "No sent messages found.", + "identityDevices_title": "Devices", + "identityDevices_title_description": "View devices of this Identity", + "identityDevices_username": "Username", + "identityDevices_communicationLanguage": "Communication Language", "identityRelationshipTable_peer": "Peer", "identityRelationshipTable_requestedBy": "Requested By", "identityRelationshipTable_templateId": "Template ID", diff --git a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart index 21ce62aa8c..8c9b92f4b8 100644 --- a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart +++ b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart @@ -9,12 +9,14 @@ class IdentityDevice { final DateTime createdAt; final String createdByDevice; final Map? lastLogin; + final String communicationLanguage; IdentityDevice({ required this.id, required this.username, required this.createdAt, required this.createdByDevice, + required this.communicationLanguage, this.lastLogin, }); diff --git a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart index dd8a2d195f..fd1e5cf4f3 100644 --- a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart +++ b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart @@ -11,6 +11,7 @@ IdentityDevice _$IdentityDeviceFromJson(Map json) => IdentityDe username: json['username'] as String, createdAt: DateTime.parse(json['createdAt'] as String), createdByDevice: json['createdByDevice'] as String, + communicationLanguage: json['communicationLanguage'] as String, lastLogin: json['lastLogin'] as Map?, ); @@ -20,4 +21,5 @@ Map _$IdentityDeviceToJson(IdentityDevice instance) => Date: Mon, 14 Oct 2024 21:47:36 +0200 Subject: [PATCH 2/4] fix: wrongly accessed time parameter from a map dynamic --- .../identity_details/identity_devices/identity_devices.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart index 989e1aa869..d87d2cbf53 100644 --- a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart +++ b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart @@ -49,7 +49,10 @@ class IdentityDevices extends StatelessWidget { ), DataCell( Text( - device.lastLogin!.isEmpty ? '${device.lastLogin!.entries.first}' : '-', + device.lastLogin != null && device.lastLogin!['time'] is String + ? DateFormat.yMd(Localizations.localeOf(context).languageCode) + .format(DateTime.parse(device.lastLogin!['time'] as String)) + : '-', style: TextStyle(color: textColor), ), ), From 1f9561dab0570ed7f972041fb869130c1f624c20 Mon Sep 17 00:00:00 2001 From: Vladimir Vuckovic Date: Tue, 15 Oct 2024 08:22:47 +0200 Subject: [PATCH 3/4] fix: remove unnecessary comparison --- .../identity_details/identity_devices/identity_devices.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart index d87d2cbf53..b7c7ef4cc0 100644 --- a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart +++ b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart @@ -49,7 +49,7 @@ class IdentityDevices extends StatelessWidget { ), DataCell( Text( - device.lastLogin != null && device.lastLogin!['time'] is String + device.lastLogin != null ? DateFormat.yMd(Localizations.localeOf(context).languageCode) .format(DateTime.parse(device.lastLogin!['time'] as String)) : '-', From 594cad760059432e852c99bd3cd618c9d3bd25b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= Date: Tue, 15 Oct 2024 10:12:52 +0200 Subject: [PATCH 4/4] fix: move to object --- .../identity_devices/identity_devices.dart | 3 +-- .../lib/src/identities/identity_device.dart | 12 +++++++++++- .../lib/src/identities/identity_device.g.dart | 10 +++++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart index b7c7ef4cc0..9f794a1c45 100644 --- a/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart +++ b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart @@ -50,8 +50,7 @@ class IdentityDevices extends StatelessWidget { DataCell( Text( device.lastLogin != null - ? DateFormat.yMd(Localizations.localeOf(context).languageCode) - .format(DateTime.parse(device.lastLogin!['time'] as String)) + ? DateFormat.yMd(Localizations.localeOf(context).languageCode).format(device.lastLogin!.time) : '-', style: TextStyle(color: textColor), ), diff --git a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart index 8c9b92f4b8..305e375e63 100644 --- a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart +++ b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.dart @@ -8,7 +8,7 @@ class IdentityDevice { final String username; final DateTime createdAt; final String createdByDevice; - final Map? lastLogin; + final LastLoginInformation? lastLogin; final String communicationLanguage; IdentityDevice({ @@ -23,3 +23,13 @@ class IdentityDevice { factory IdentityDevice.fromJson(dynamic json) => _$IdentityDeviceFromJson(json as Map); Map toJson() => _$IdentityDeviceToJson(this); } + +@JsonSerializable() +class LastLoginInformation { + final DateTime time; + + LastLoginInformation({required this.time}); + + factory LastLoginInformation.fromJson(dynamic json) => _$LastLoginInformationFromJson(json as Map); + Map toJson() => _$LastLoginInformationToJson(this); +} diff --git a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart index fd1e5cf4f3..fa9bd7e269 100644 --- a/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart +++ b/Applications/AdminUi/packages/admin_api_types/lib/src/identities/identity_device.g.dart @@ -12,7 +12,7 @@ IdentityDevice _$IdentityDeviceFromJson(Map json) => IdentityDe createdAt: DateTime.parse(json['createdAt'] as String), createdByDevice: json['createdByDevice'] as String, communicationLanguage: json['communicationLanguage'] as String, - lastLogin: json['lastLogin'] as Map?, + lastLogin: json['lastLogin'] == null ? null : LastLoginInformation.fromJson(json['lastLogin']), ); Map _$IdentityDeviceToJson(IdentityDevice instance) => { @@ -23,3 +23,11 @@ Map _$IdentityDeviceToJson(IdentityDevice instance) => json) => LastLoginInformation( + time: DateTime.parse(json['time'] as String), + ); + +Map _$LastLoginInformationToJson(LastLoginInformation instance) => { + 'time': instance.time.toIso8601String(), + };