diff --git a/elixir/apps/web/lib/web/components/core_components.ex b/elixir/apps/web/lib/web/components/core_components.ex
index 02de65900..be5627899 100644
--- a/elixir/apps/web/lib/web/components/core_components.ex
+++ b/elixir/apps/web/lib/web/components/core_components.ex
@@ -771,19 +771,53 @@ defmodule Web.CoreComponents do
assigns = assign_new(assigns, :relative_to, fn -> DateTime.utc_now() end)
~H"""
-
- <%= Cldr.DateTime.Relative.to_string!(@datetime, Web.CLDR, relative_to: @relative_to) %>
-
+ <.popover :if={not is_nil(@datetime)}>
+ <:target>
+
+ <%= Cldr.DateTime.Relative.to_string!(@datetime, Web.CLDR, relative_to: @relative_to)
+ |> String.capitalize() %>
+
+
+ <:content>
+ <%= @datetime %>
+
+
- never
+ Never
"""
end
+ @doc """
+ Renders a popover element with title and content.
+ """
+ slot :target, required: true
+ slot :content, required: true
+
+ def popover(assigns) do
+ # Any id will do
+ target_id = "popover-#{System.unique_integer([:positive, :monotonic])}"
+ assigns = assign(assigns, :target_id, target_id)
+
+ ~H"""
+
+ <%= render_slot(@target) %>
+
+
+
+
+ <%= render_slot(@content) %>
+
+
+
+ """
+ end
+
@doc """
Renders online or offline status using an `online?` field of the schema.
"""
diff --git a/elixir/apps/web/lib/web/live/policies/show.ex b/elixir/apps/web/lib/web/live/policies/show.ex
index 0fe4f13fe..5f5940093 100644
--- a/elixir/apps/web/lib/web/live/policies/show.ex
+++ b/elixir/apps/web/lib/web/live/policies/show.ex
@@ -150,13 +150,7 @@ defmodule Web.Policies.Show do
Created
<:value>
- <.datetime datetime={@policy.inserted_at} /> by
- <.link
- navigate={~p"/#{@account}/actors/#{@policy.created_by_identity.actor.id}"}
- class={link_style()}
- >
- <%= @policy.created_by_identity.actor.name %>
-
+ <.created_by account={@account} schema={@policy} />
diff --git a/elixir/apps/web/test/support/conn_case.ex b/elixir/apps/web/test/support/conn_case.ex
index cc908e981..9dc9a3365 100644
--- a/elixir/apps/web/test/support/conn_case.ex
+++ b/elixir/apps/web/test/support/conn_case.ex
@@ -202,7 +202,7 @@ defmodule Web.ConnCase do
### Helpers to test formatted time units
def around_now?(string) do
- if string =~ "now" do
+ if string =~ "Now" do
true
else
[_all, seconds] = Regex.run(~r/([0-9]+) second[s]? ago/, string)
diff --git a/elixir/apps/web/test/web/live/actors/index_test.exs b/elixir/apps/web/test/web/live/actors/index_test.exs
index 06747b235..2b5184205 100644
--- a/elixir/apps/web/test/web/live/actors/index_test.exs
+++ b/elixir/apps/web/test/web/live/actors/index_test.exs
@@ -99,7 +99,7 @@ defmodule Web.Live.Actors.IndexTest do
assert row["groups"] =~ group.name
end
- assert row["last signed in"] == "never"
+ assert row["last signed in"] == "Never"
end)
end
end
@@ -133,7 +133,7 @@ defmodule Web.Live.Actors.IndexTest do
|> render()
|> table_to_map()
|> with_table_row("name", actor.name, fn row ->
- assert row["last signed in"] == "1 hour ago"
+ assert String.contains?(row["last signed in"], "1 hour ago")
end)
end
end
diff --git a/elixir/apps/web/test/web/live/actors/show_test.exs b/elixir/apps/web/test/web/live/actors/show_test.exs
index 2bcfca2a4..e630b3efb 100644
--- a/elixir/apps/web/test/web/live/actors/show_test.exs
+++ b/elixir/apps/web/test/web/live/actors/show_test.exs
@@ -359,7 +359,7 @@ defmodule Web.Live.Actors.ShowTest do
fn row ->
assert row["actions"] =~ "Delete"
assert row["created"] =~ "by #{actor.name}"
- assert row["last signed in"] == "never"
+ assert row["last signed in"] == "Never"
end
)
|> with_table_row(
@@ -368,7 +368,7 @@ defmodule Web.Live.Actors.ShowTest do
fn row ->
refute row["actions"]
assert row["created"] =~ "by #{synced_identity.provider.name} sync"
- assert row["last signed in"] == "never"
+ assert row["last signed in"] == "Never"
end
)
end
@@ -661,14 +661,20 @@ defmodule Web.Live.Actors.ShowTest do
|> table_to_map()
assert row1["type"] == "browser"
- assert row1["expires"] in ["tomorrow", "in 24 hours"]
- assert row1["last used"] == "never"
+
+ assert String.contains?(row1["expires"], "Tomorrow") ||
+ String.contains?(row1["expires"], "In 24 hours")
+
+ assert row1["last used"] == "Never"
assert around_now?(row1["created"])
assert row1["actions"] == "Revoke"
assert row2["type"] == "client"
- assert row2["expires"] in ["tomorrow", "in 24 hours"]
- assert row2["last used"] == "never"
+
+ assert String.contains?(row2["expires"], "Tomorrow") ||
+ String.contains?(row2["expires"], "In 24 hours")
+
+ assert row2["last used"] == "Never"
assert around_now?(row2["created"])
assert row2["actions"] == "Revoke"
end
@@ -928,7 +934,7 @@ defmodule Web.Live.Actors.ShowTest do
|> element("#actor")
|> render()
|> vertical_table_to_map() == %{
- "last signed in" => "never",
+ "last signed in" => "Never",
"name" => actor.name,
"role" => "service account"
}
@@ -1084,14 +1090,20 @@ defmodule Web.Live.Actors.ShowTest do
|> table_to_map()
assert row1["type"] == "browser"
- assert row1["expires"] in ["tomorrow", "in 24 hours"]
- assert row1["last used"] == "never"
+
+ assert String.contains?(row1["expires"], "Tomorrow") ||
+ String.contains?(row1["expires"], "In 24 hours")
+
+ assert row1["last used"] == "Never"
assert around_now?(row1["created"])
assert row1["actions"] == "Revoke"
assert row2["type"] == "client"
- assert row2["expires"] in ["tomorrow", "in 24 hours"]
- assert row2["last used"] == "never"
+
+ assert String.contains?(row2["expires"], "Tomorrow") ||
+ String.contains?(row2["expires"], "In 24 hours")
+
+ assert row2["last used"] == "Never"
assert around_now?(row2["created"])
assert row2["actions"] == "Revoke"
end
diff --git a/elixir/apps/web/test/web/live/settings/api_clients/show_test.exs b/elixir/apps/web/test/web/live/settings/api_clients/show_test.exs
index 739f86fec..607b032d3 100644
--- a/elixir/apps/web/test/web/live/settings/api_clients/show_test.exs
+++ b/elixir/apps/web/test/web/live/settings/api_clients/show_test.exs
@@ -214,7 +214,7 @@ defmodule Web.Live.Settings.ApiClients.ShowTest do
assert row1["name"] == token.name
assert row1["expires at"]
- assert row1["last used"] == "never"
+ assert row1["last used"] == "Never"
assert row1["actions"] == "Revoke"
end
diff --git a/elixir/apps/web/test/web/live/settings/identity_providers/index_test.exs b/elixir/apps/web/test/web/live/settings/identity_providers/index_test.exs
index bb14752c9..f14fbe737 100644
--- a/elixir/apps/web/test/web/live/settings/identity_providers/index_test.exs
+++ b/elixir/apps/web/test/web/live/settings/identity_providers/index_test.exs
@@ -140,7 +140,7 @@ defmodule Web.Live.Settings.IdentityProviders.IndexTest do
|> render()
|> table_to_map()
|> with_table_row("name", provider.name, fn row ->
- assert row["sync status"] == "Synced 2 identities and 1 group 1 hour ago"
+ assert String.contains?(row["sync status"], "Synced 2 identities and 1 group 1 hour ago")
end)
provider =