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..9f794a1c45 --- /dev/null +++ b/Applications/AdminUi/apps/admin_ui/lib/home/identity_details/identity_devices/identity_devices.dart @@ -0,0 +1,72 @@ +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 != null + ? DateFormat.yMd(Localizations.localeOf(context).languageCode).format(device.lastLogin!.time) + : '-', + 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..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,16 +8,28 @@ class IdentityDevice { final String username; final DateTime createdAt; final String createdByDevice; - final Map? lastLogin; + final LastLoginInformation? lastLogin; + final String communicationLanguage; IdentityDevice({ required this.id, required this.username, required this.createdAt, required this.createdByDevice, + required this.communicationLanguage, this.lastLogin, }); 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 dd8a2d195f..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 @@ -11,7 +11,8 @@ IdentityDevice _$IdentityDeviceFromJson(Map json) => IdentityDe username: json['username'] as String, createdAt: DateTime.parse(json['createdAt'] as String), createdByDevice: json['createdByDevice'] as String, - lastLogin: json['lastLogin'] as Map?, + communicationLanguage: json['communicationLanguage'] as String, + lastLogin: json['lastLogin'] == null ? null : LastLoginInformation.fromJson(json['lastLogin']), ); Map _$IdentityDeviceToJson(IdentityDevice instance) => { @@ -20,4 +21,13 @@ Map _$IdentityDeviceToJson(IdentityDevice instance) => json) => LastLoginInformation( + time: DateTime.parse(json['time'] as String), + ); + +Map _$LastLoginInformationToJson(LastLoginInformation instance) => { + 'time': instance.time.toIso8601String(), };