From 5f59801430417e7859a1c4b56c3ee4786ba7474d Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Tue, 3 Feb 2026 14:43:18 +1100
Subject: [PATCH 1/8] Add views and update workspace assembly paths
---
.../App/User Details/src/UserDetails.Page.al | 68 ++++++++++++++++++-
.../App/User Details/src/UserDetails.Table.al | 33 +++++++++
src/SystemApplication.code-workspace | 14 +++-
3 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/src/System Application/App/User Details/src/UserDetails.Page.al b/src/System Application/App/User Details/src/UserDetails.Page.al
index da33aaece1..e1570696a3 100644
--- a/src/System Application/App/User Details/src/UserDetails.Page.al
+++ b/src/System Application/App/User Details/src/UserDetails.Page.al
@@ -6,6 +6,8 @@
namespace System.Security.User;
using System.Environment;
+using System.Security.AccessControl;
+using System.Utilities;
///
/// Shows detailed user information, such as unique identifiers, information about permission sets etc.
@@ -15,7 +17,7 @@ page 774 "User Details"
AboutText = 'View the additional information about users in a list view, which allows for easy searching and filtering.';
AboutTitle = 'About the users detailed view';
ApplicationArea = Basic, Suite;
- Caption = 'Users';
+ Caption = 'Users (detailed view)';
DeleteAllowed = false;
Editable = false;
InsertAllowed = false;
@@ -67,6 +69,36 @@ page 774 "User Details"
ToolTip = 'Specifies ID assigned to the user in Microsoft Entra.';
Visible = IsSaaS;
}
+ field("Last Login Date"; Rec."Last Login Date")
+ {
+ Caption = 'Last Login Date';
+ ToolTip = 'Specifies the date and time when the user last logged in.';
+ }
+ field("InactiveDays"; InactiveDays)
+ {
+ Caption = 'Inactive (days)';
+ ToolTip = 'Specifies the number of days since the user last logged in.';
+ }
+ field(SystemCreatedAt; SystemCreatedAt)
+ {
+ Caption = 'Created On';
+ ToolTip = 'Specifies the date and time when the user record was created.';
+ }
+ field(CreatedBy; CreatedByUser."User Name")
+ {
+ Caption = 'Created By';
+ ToolTip = 'Specifies the user who created the user record.';
+ }
+ field(SystemModifiedAt; SystemModifiedAt)
+ {
+ Caption = 'Modified On';
+ ToolTip = 'Specifies the date and time when the user record was last modified.';
+ }
+ field(ModifiedBy; ModifiedByUser."User Name")
+ {
+ Caption = 'Modified By';
+ ToolTip = 'Specifies the user who last modified the user record.';
+ }
// Can be added with "Personalize"
field("Has SUPER permission set"; Rec."Has SUPER permission set")
{
@@ -89,6 +121,21 @@ page 774 "User Details"
Caption = 'Users with SUPER permission set';
Filters = where("Has SUPER permission set" = const(true));
}
+ view("7 Days")
+ {
+ Caption = '7 days (last week)';
+ Filters = where("Last Login Date" = field("7 Days Date Filter"));
+ }
+ view("30 Days")
+ {
+ Caption = '30 days (last month)';
+ Filters = where("Last Login Date" = field("30 Days Date Filter"));
+ }
+ view("90 Days")
+ {
+ Caption = '90 days (quarter)';
+ Filters = where("Last Login Date" = field("90 Days Date Filter"));
+ }
}
trigger OnOpenPage()
@@ -98,8 +145,27 @@ page 774 "User Details"
begin
IsSaaS := EnvironmentInformation.IsSaaS();
UserDetails.Get(Rec);
+
+ Rec.SetFilter("7 Days Date Filter", '>%1', CreateDateTime(CalcDate('<-7D>', Today()), CurrentDateTime().Time));
+ Rec.SetFilter("30 Days Date Filter", '>%1', CreateDateTime(CalcDate('<-30D>', Today()), CurrentDateTime().Time));
+ Rec.SetFilter("90 Days Date Filter", '>%1', CreateDateTime(CalcDate('<-90D>', Today()), CurrentDateTime().Time));
end;
+ trigger OnAfterGetRecord()
+ var
+ Math: Codeunit Math;
+ begin
+ if CreatedByUser.Get(Rec.SystemCreatedBy) then;
+ if ModifiedByUser.Get(Rec.SystemModifiedBy) then;
+ if Rec."Last Login Date".Date <> 0D then
+ InactiveDays := Math.Floor(Today() - Rec."Last Login Date".Date);
+ end;
+
+ var
+ CreatedByUser: Record User;
+ ModifiedByUser: Record User;
+ InactiveDays: Integer;
+
protected var
IsSaaS: Boolean;
}
\ No newline at end of file
diff --git a/src/System Application/App/User Details/src/UserDetails.Table.al b/src/System Application/App/User Details/src/UserDetails.Table.al
index 34100bacc4..c208fe1231 100644
--- a/src/System Application/App/User Details/src/UserDetails.Table.al
+++ b/src/System Application/App/User Details/src/UserDetails.Table.al
@@ -116,6 +116,39 @@ table 774 "User Details"
Editable = false;
FieldClass = FlowField;
}
+ ///
+ /// The last login date of the user.
+ ///
+ field(24; "Last Login Date"; DateTime)
+ {
+ Caption = 'Last Login Date';
+ FieldClass = FlowField;
+ CalcFormula = Lookup("User Login"."Last Login Date" where("User SID" = field("User Security ID")));
+ }
+ ///
+ /// Flow filter for determining users who logged in within the last 7 days.
+ ///
+ field(25; "7 Days Date Filter"; DateTime)
+ {
+ Caption = 'Last 7 Days Filter';
+ FieldClass = FlowFilter;
+ }
+ ///
+ /// Flow filter for determining users who logged in within the last 30 days.
+ ///
+ field(26; "30 Days Date Filter"; DateTime)
+ {
+ Caption = 'Last 30 Days Filter';
+ FieldClass = FlowFilter;
+ }
+ ///
+ /// Flow filter for determining users who logged in within the last 90 days.
+ ///
+ field(27; "90 Days Date Filter"; DateTime)
+ {
+ Caption = 'Last 90 Days Filter';
+ FieldClass = FlowFilter;
+ }
}
keys
diff --git a/src/SystemApplication.code-workspace b/src/SystemApplication.code-workspace
index f08e9feb23..498209c59d 100644
--- a/src/SystemApplication.code-workspace
+++ b/src/SystemApplication.code-workspace
@@ -32,5 +32,17 @@
"name": "System Application Tests",
"path": "System Application\\Test"
}
- ]
+ ],
+ "settings": {
+ "al.assemblyProbingPaths": [
+ "./.netpackages",
+ "C:/Users/ben.plunkett/Business central installs/260.29145/Service/Add-ins",
+ "C:/Users/ben.plunkett/Business central installs/260.29145/Service/Admin",
+ "C:/Users/ben.plunkett/Business central installs/280.42318/ServiceTier/PFiles64/Microsoft Dynamics NAV/280/Service",
+ "C:/Users/ben.plunkett/Business central installs/280.42318/ServiceTier/PFiles64/Microsoft Dynamics NAV/280/Service/Add-ins",
+ "C:/Users/ben.plunkett/Business central installs/280.42318/ServiceTier/PFiles64/Microsoft Dynamics NAV/280/Service/Admin",
+ "C:/Program Files/dotnet/shared/Microsoft.AspNetCore.App/8.0.22",
+ "C:/Program Files/dotnet/shared/Microsoft.NETCore.App/8.0.22"
+ ],
+ }
}
\ No newline at end of file
From f07de3374d42dd810beb097b6adaac186fbec34b Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Wed, 4 Feb 2026 13:00:53 +1100
Subject: [PATCH 2/8] Update User Detail views
---
.../src/UserDetailDateFilter.Enum.al | 19 +++++++++
.../App/User Details/src/UserDetails.Page.al | 42 ++++++++++++++-----
.../App/User Details/src/UserDetails.Table.al | 22 ++--------
3 files changed, 54 insertions(+), 29 deletions(-)
create mode 100644 src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
diff --git a/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
new file mode 100644
index 0000000000..a2ae63c74c
--- /dev/null
+++ b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
@@ -0,0 +1,19 @@
+enum 774 "User Detail Date Filter"
+{
+ value(0; Blank)
+ {
+ }
+
+ value(1; "7Days")
+ {
+ Caption = '7 Days';
+ }
+ value(2; "30Days")
+ {
+ Caption = '30 Days';
+ }
+ value(3; "90Days")
+ {
+ Caption = '90 Days';
+ }
+}
\ No newline at end of file
diff --git a/src/System Application/App/User Details/src/UserDetails.Page.al b/src/System Application/App/User Details/src/UserDetails.Page.al
index e1570696a3..d7c26905d5 100644
--- a/src/System Application/App/User Details/src/UserDetails.Page.al
+++ b/src/System Application/App/User Details/src/UserDetails.Page.al
@@ -14,7 +14,7 @@ using System.Utilities;
///
page 774 "User Details"
{
- AboutText = 'View the additional information about users in a list view, which allows for easy searching and filtering.';
+ AboutText = 'View detailed user information, such as unique identifiers, information about permission sets, login activity etc. in a list view, which allows for easy searching and filtering.';
AboutTitle = 'About the users detailed view';
ApplicationArea = Basic, Suite;
Caption = 'Users (detailed view)';
@@ -123,18 +123,18 @@ page 774 "User Details"
}
view("7 Days")
{
- Caption = '7 days (last week)';
- Filters = where("Last Login Date" = field("7 Days Date Filter"));
+ Caption = 'Inactive 7 days';
+ Filters = where("Inactive Days Date Filter" = const("7Days"));
}
view("30 Days")
{
- Caption = '30 days (last month)';
- Filters = where("Last Login Date" = field("30 Days Date Filter"));
+ Caption = 'Inactive 30 days';
+ Filters = where("Inactive Days Date Filter" = const("30Days"));
}
view("90 Days")
{
- Caption = '90 days (quarter)';
- Filters = where("Last Login Date" = field("90 Days Date Filter"));
+ Caption = 'Inactive 90 days';
+ Filters = where("Inactive Days Date Filter" = const("90Days"));
}
}
@@ -145,10 +145,27 @@ page 774 "User Details"
begin
IsSaaS := EnvironmentInformation.IsSaaS();
UserDetails.Get(Rec);
+ end;
+
+ trigger OnFindRecord(Which: Text): Boolean
+ var
+ UserDetails: Record "User Details";
+ begin
+ Rec.SetRange("Last Login Date");
+ if Rec.GetFilter("Inactive Days Date Filter") <> '' then
+ if Evaluate(UserDetails."Inactive Days Date Filter", Rec.GetFilter("Inactive Days Date Filter")) then
+ case UserDetails."Inactive Days Date Filter" of
+ Rec."Inactive Days Date Filter"::"7Days":
+ Rec.SetFilter("Last Login Date", '<=%1', CreateDateTime(CalcDate('<-7D>', Today()), CurrentDateTime().Time));
+ Rec."Inactive Days Date Filter"::"30Days":
+ Rec.SetFilter("Last Login Date", '<=%1', CreateDateTime(CalcDate('<-30D>', Today()), CurrentDateTime().Time));
+ Rec."Inactive Days Date Filter"::"90Days":
+ Rec.SetFilter("Last Login Date", '<=%1', CreateDateTime(CalcDate('<-90D>', Today()), CurrentDateTime().Time));
+ else
+ OnInactiveDaysFilterCaseElse(UserDetails."Inactive Days Date Filter", Rec);
+ end;
- Rec.SetFilter("7 Days Date Filter", '>%1', CreateDateTime(CalcDate('<-7D>', Today()), CurrentDateTime().Time));
- Rec.SetFilter("30 Days Date Filter", '>%1', CreateDateTime(CalcDate('<-30D>', Today()), CurrentDateTime().Time));
- Rec.SetFilter("90 Days Date Filter", '>%1', CreateDateTime(CalcDate('<-90D>', Today()), CurrentDateTime().Time));
+ exit(Rec.Find(Which));
end;
trigger OnAfterGetRecord()
@@ -168,4 +185,9 @@ page 774 "User Details"
protected var
IsSaaS: Boolean;
+
+ [IntegrationEvent(false, false)]
+ local procedure OnInactiveDaysFilterCaseElse(DateFilter: Enum "User Detail Date Filter"; var Rec: Record "User Details")
+ begin
+ end;
}
\ No newline at end of file
diff --git a/src/System Application/App/User Details/src/UserDetails.Table.al b/src/System Application/App/User Details/src/UserDetails.Table.al
index c208fe1231..7c62dc0176 100644
--- a/src/System Application/App/User Details/src/UserDetails.Table.al
+++ b/src/System Application/App/User Details/src/UserDetails.Table.al
@@ -126,27 +126,11 @@ table 774 "User Details"
CalcFormula = Lookup("User Login"."Last Login Date" where("User SID" = field("User Security ID")));
}
///
- /// Flow filter for determining users who logged in within the last 7 days.
+ /// Flow filter for filtering users based on Last Login Date.
///
- field(25; "7 Days Date Filter"; DateTime)
+ field(25; "Inactive Days Date Filter"; Enum "User Detail Date Filter")
{
- Caption = 'Last 7 Days Filter';
- FieldClass = FlowFilter;
- }
- ///
- /// Flow filter for determining users who logged in within the last 30 days.
- ///
- field(26; "30 Days Date Filter"; DateTime)
- {
- Caption = 'Last 30 Days Filter';
- FieldClass = FlowFilter;
- }
- ///
- /// Flow filter for determining users who logged in within the last 90 days.
- ///
- field(27; "90 Days Date Filter"; DateTime)
- {
- Caption = 'Last 90 Days Filter';
+ Caption = 'Inactive Days Date Filter';
FieldClass = FlowFilter;
}
}
From c00c4d75019877f6297bf7bfa46145a174c0fc81 Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Wed, 4 Feb 2026 13:02:20 +1100
Subject: [PATCH 3/8] Add copyright
---
.../App/User Details/src/UserDetailDateFilter.Enum.al | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
index a2ae63c74c..4968ccac74 100644
--- a/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
+++ b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
@@ -1,3 +1,8 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
enum 774 "User Detail Date Filter"
{
value(0; Blank)
From b860295c7b9de518e77cf927d84cae276f47fdf4 Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Wed, 4 Feb 2026 13:41:37 +1100
Subject: [PATCH 4/8] Removed assembly paths
---
src/SystemApplication.code-workspace | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/src/SystemApplication.code-workspace b/src/SystemApplication.code-workspace
index 498209c59d..f08e9feb23 100644
--- a/src/SystemApplication.code-workspace
+++ b/src/SystemApplication.code-workspace
@@ -32,17 +32,5 @@
"name": "System Application Tests",
"path": "System Application\\Test"
}
- ],
- "settings": {
- "al.assemblyProbingPaths": [
- "./.netpackages",
- "C:/Users/ben.plunkett/Business central installs/260.29145/Service/Add-ins",
- "C:/Users/ben.plunkett/Business central installs/260.29145/Service/Admin",
- "C:/Users/ben.plunkett/Business central installs/280.42318/ServiceTier/PFiles64/Microsoft Dynamics NAV/280/Service",
- "C:/Users/ben.plunkett/Business central installs/280.42318/ServiceTier/PFiles64/Microsoft Dynamics NAV/280/Service/Add-ins",
- "C:/Users/ben.plunkett/Business central installs/280.42318/ServiceTier/PFiles64/Microsoft Dynamics NAV/280/Service/Admin",
- "C:/Program Files/dotnet/shared/Microsoft.AspNetCore.App/8.0.22",
- "C:/Program Files/dotnet/shared/Microsoft.NETCore.App/8.0.22"
- ],
- }
+ ]
}
\ No newline at end of file
From 34370f7d16cdfdc25467c9e6415f24f33584d48d Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Mon, 9 Feb 2026 17:52:45 +1100
Subject: [PATCH 5/8] Updates from review
---
.../App/User Details/src/UserDetailDateFilter.Enum.al | 7 +++----
.../App/User Details/src/UserDetails.Page.al | 2 +-
.../App/User Details/src/UserDetails.Table.al | 4 ++++
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
index 4968ccac74..172afcd188 100644
--- a/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
+++ b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
@@ -8,16 +8,15 @@ enum 774 "User Detail Date Filter"
value(0; Blank)
{
}
-
- value(1; "7Days")
+ value(1; "7 Days")
{
Caption = '7 Days';
}
- value(2; "30Days")
+ value(2; "30 Days")
{
Caption = '30 Days';
}
- value(3; "90Days")
+ value(3; "90 Days")
{
Caption = '90 Days';
}
diff --git a/src/System Application/App/User Details/src/UserDetails.Page.al b/src/System Application/App/User Details/src/UserDetails.Page.al
index d7c26905d5..0f6f8c9371 100644
--- a/src/System Application/App/User Details/src/UserDetails.Page.al
+++ b/src/System Application/App/User Details/src/UserDetails.Page.al
@@ -74,7 +74,7 @@ page 774 "User Details"
Caption = 'Last Login Date';
ToolTip = 'Specifies the date and time when the user last logged in.';
}
- field("InactiveDays"; InactiveDays)
+ field("Inactive Days"; InactiveDays)
{
Caption = 'Inactive (days)';
ToolTip = 'Specifies the number of days since the user last logged in.';
diff --git a/src/System Application/App/User Details/src/UserDetails.Table.al b/src/System Application/App/User Details/src/UserDetails.Table.al
index 7c62dc0176..3f4b015a0c 100644
--- a/src/System Application/App/User Details/src/UserDetails.Table.al
+++ b/src/System Application/App/User Details/src/UserDetails.Table.al
@@ -121,7 +121,9 @@ table 774 "User Details"
///
field(24; "Last Login Date"; DateTime)
{
+ Access = Internal;
Caption = 'Last Login Date';
+ Editable = false;
FieldClass = FlowField;
CalcFormula = Lookup("User Login"."Last Login Date" where("User SID" = field("User Security ID")));
}
@@ -130,7 +132,9 @@ table 774 "User Details"
///
field(25; "Inactive Days Date Filter"; Enum "User Detail Date Filter")
{
+ Access = Internal;
Caption = 'Inactive Days Date Filter';
+ Editable = false;
FieldClass = FlowFilter;
}
}
From f92b98ef35e6318819df80e4cffaa976d6693559 Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Mon, 9 Feb 2026 17:54:42 +1100
Subject: [PATCH 6/8] User details date filter update
---
.../App/User Details/src/UserDetailDateFilter.Enum.al | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
index 172afcd188..a865626d40 100644
--- a/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
+++ b/src/System Application/App/User Details/src/UserDetailDateFilter.Enum.al
@@ -3,6 +3,12 @@
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
+namespace System.Security.User;
+
+
+///
+/// Used for setting date flow filters against the Last Login time field on the user details page.
+///
enum 774 "User Detail Date Filter"
{
value(0; Blank)
From eabdc32dc1459e19356e5b3aa2a830028cfe90cf Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Tue, 10 Feb 2026 09:24:56 +1100
Subject: [PATCH 7/8] Fix enums
---
.../App/User Details/src/UserDetails.Page.al | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/System Application/App/User Details/src/UserDetails.Page.al b/src/System Application/App/User Details/src/UserDetails.Page.al
index 0f6f8c9371..e4853d3b8c 100644
--- a/src/System Application/App/User Details/src/UserDetails.Page.al
+++ b/src/System Application/App/User Details/src/UserDetails.Page.al
@@ -124,17 +124,17 @@ page 774 "User Details"
view("7 Days")
{
Caption = 'Inactive 7 days';
- Filters = where("Inactive Days Date Filter" = const("7Days"));
+ Filters = where("Inactive Days Date Filter" = const("7 Days"));
}
view("30 Days")
{
Caption = 'Inactive 30 days';
- Filters = where("Inactive Days Date Filter" = const("30Days"));
+ Filters = where("Inactive Days Date Filter" = const("30 Days"));
}
view("90 Days")
{
Caption = 'Inactive 90 days';
- Filters = where("Inactive Days Date Filter" = const("90Days"));
+ Filters = where("Inactive Days Date Filter" = const("90 Days"));
}
}
From 83c765f18d8f1e424eb57184bad7d7b3e0a6a89d Mon Sep 17 00:00:00 2001
From: "FENWICK\\ben.plunkett" <42510084+BenPlunk@users.noreply.github.com>
Date: Tue, 10 Feb 2026 16:00:42 +1100
Subject: [PATCH 8/8] Update caption capitalisation
---
src/System Application/App/User Details/src/UserDetails.Page.al | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System Application/App/User Details/src/UserDetails.Page.al b/src/System Application/App/User Details/src/UserDetails.Page.al
index e4853d3b8c..2363a794a5 100644
--- a/src/System Application/App/User Details/src/UserDetails.Page.al
+++ b/src/System Application/App/User Details/src/UserDetails.Page.al
@@ -17,7 +17,7 @@ page 774 "User Details"
AboutText = 'View detailed user information, such as unique identifiers, information about permission sets, login activity etc. in a list view, which allows for easy searching and filtering.';
AboutTitle = 'About the users detailed view';
ApplicationArea = Basic, Suite;
- Caption = 'Users (detailed view)';
+ Caption = 'Users (Detailed View)';
DeleteAllowed = false;
Editable = false;
InsertAllowed = false;