From 140a2979dadbe4f45b2c0a3885fc8cc46378f545 Mon Sep 17 00:00:00 2001 From: Jamil Date: Thu, 4 Jul 2024 09:37:33 -0700 Subject: [PATCH] refactor(portal): Use popover with UTC timestamp for datetime fields (#5712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #5249 to allow copy-pasting the timestamp Fixes #5635 by virtue of using a relative datetime there. Fixes #5225 Screenshot 2024-07-03 at 10 58 11 PM --- .../web/lib/web/components/core_components.ex | 50 ++++++++++++++++--- elixir/apps/web/lib/web/live/policies/show.ex | 8 +-- elixir/apps/web/test/support/conn_case.ex | 2 +- .../web/test/web/live/actors/index_test.exs | 4 +- .../web/test/web/live/actors/show_test.exs | 34 +++++++++---- .../live/settings/api_clients/show_test.exs | 2 +- .../identity_providers/index_test.exs | 2 +- 7 files changed, 71 insertions(+), 31 deletions(-) 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) %> + + + + """ + 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 =