From e86190c3ebb1416fa62eb0dbfa834e69c30d2dfb Mon Sep 17 00:00:00 2001 From: Andrew Dryga Date: Wed, 24 Apr 2024 15:45:48 -0600 Subject: [PATCH] feat(portal): Allow creating resources from Resources page (#4775) Closes #4625 --- .../domain/jobs/executors/concurrent_test.exs | 1 - .../web/lib/web/live/resources/components.ex | 26 +++++- .../apps/web/lib/web/live/resources/edit.ex | 1 + .../apps/web/lib/web/live/resources/index.ex | 7 +- elixir/apps/web/lib/web/live/resources/new.ex | 1 + .../test/web/live/resources/index_test.exs | 2 +- .../web/test/web/live/resources/new_test.exs | 85 ++++++++++++++++++- elixir/mix.lock | 10 +-- 8 files changed, 119 insertions(+), 14 deletions(-) diff --git a/elixir/apps/domain/test/domain/jobs/executors/concurrent_test.exs b/elixir/apps/domain/test/domain/jobs/executors/concurrent_test.exs index 880559ae1..9f660833b 100644 --- a/elixir/apps/domain/test/domain/jobs/executors/concurrent_test.exs +++ b/elixir/apps/domain/test/domain/jobs/executors/concurrent_test.exs @@ -1,6 +1,5 @@ defmodule Domain.Jobs.Executors.ConcurrentTest do use Domain.DataCase, async: true - alias Domain.Fixtures import Domain.Jobs.Executors.Concurrent def state(config) do diff --git a/elixir/apps/web/lib/web/live/resources/components.ex b/elixir/apps/web/lib/web/live/resources/components.ex index 5ea4d2491..d79d73c86 100644 --- a/elixir/apps/web/lib/web/live/resources/components.ex +++ b/elixir/apps/web/lib/web/live/resources/components.ex @@ -207,9 +207,33 @@ defmodule Web.Resources.Components do attr :account, :any, required: true attr :gateway_groups, :list, required: true attr :resource, :any, default: nil + attr :multiple, :boolean, required: true attr :rest, :global - def connections_form(assigns) do + def connections_form(%{multiple: false} = assigns) do + ~H""" + <% connected_gateway_group_id = @form |> connected_gateway_group_ids() |> List.first() %> + + <.input type="hidden" name={"#{@form.name}[0][enabled]"} value="true" /> + <.input :if={@resource} type="hidden" name={"#{@form.name}[0][resource_id]"} value={@resource.id} /> + + <.input + type="select" + label="Site" + name={"#{@form.name}[0][gateway_group_id]"} + options={ + Enum.map(@gateway_groups, fn gateway_group -> + {gateway_group.name, gateway_group.id} + end) + } + value={connected_gateway_group_id} + placeholder="Select a Site" + required + /> + """ + end + + def connections_form(%{multiple: true} = assigns) do assigns = assign(assigns, :errors, Enum.map(assigns.form.errors, &translate_error(&1))) ~H""" diff --git a/elixir/apps/web/lib/web/live/resources/edit.ex b/elixir/apps/web/lib/web/live/resources/edit.ex index 9dd505a34..13cf98101 100644 --- a/elixir/apps/web/lib/web/live/resources/edit.ex +++ b/elixir/apps/web/lib/web/live/resources/edit.ex @@ -77,6 +77,7 @@ defmodule Web.Resources.Edit do <.connections_form :if={is_nil(@params["site_id"])} id="connections_form" + multiple={Domain.Accounts.multi_site_resources_enabled?(@account)} form={@form[:connections]} account={@account} resource={@resource} diff --git a/elixir/apps/web/lib/web/live/resources/index.ex b/elixir/apps/web/lib/web/live/resources/index.ex index c7b8e6667..4ac8c0d24 100644 --- a/elixir/apps/web/lib/web/live/resources/index.ex +++ b/elixir/apps/web/lib/web/live/resources/index.ex @@ -58,11 +58,8 @@ defmodule Web.Resources.Index do in the <.link navigate={~p"/#{@account}/sites"} class={link_style()}>Sites section. <:action> - <.add_button - :if={Domain.Accounts.multi_site_resources_enabled?(@account)} - navigate={~p"/#{@account}/resources/new"} - > - Add Multi-Site Resource + <.add_button navigate={~p"/#{@account}/resources/new"}> + Add Resource <:content> diff --git a/elixir/apps/web/lib/web/live/resources/new.ex b/elixir/apps/web/lib/web/live/resources/new.ex index 3160f10f9..efd30564c 100644 --- a/elixir/apps/web/lib/web/live/resources/new.ex +++ b/elixir/apps/web/lib/web/live/resources/new.ex @@ -134,6 +134,7 @@ defmodule Web.Resources.New do <.connections_form :if={is_nil(@params["site_id"])} + multiple={Domain.Accounts.multi_site_resources_enabled?(@account)} form={@form[:connections]} account={@account} gateway_groups={@gateway_groups} diff --git a/elixir/apps/web/test/web/live/resources/index_test.exs b/elixir/apps/web/test/web/live/resources/index_test.exs index f3c025701..998518519 100644 --- a/elixir/apps/web/test/web/live/resources/index_test.exs +++ b/elixir/apps/web/test/web/live/resources/index_test.exs @@ -49,7 +49,7 @@ defmodule Web.Live.Resources.IndexTest do |> live(~p"/#{account}/resources") assert button = Floki.find(html, "a[href='/#{account.slug}/resources/new']") - assert Floki.text(button) =~ "Add Multi-Site Resource" + assert Floki.text(button) =~ "Add Resource" end test "hides resource button when feature is disabled", %{ diff --git a/elixir/apps/web/test/web/live/resources/new_test.exs b/elixir/apps/web/test/web/live/resources/new_test.exs index 1503a9f61..eadd6faee 100644 --- a/elixir/apps/web/test/web/live/resources/new_test.exs +++ b/elixir/apps/web/test/web/live/resources/new_test.exs @@ -48,12 +48,58 @@ defmodule Web.Live.Resources.NewTest do assert breadcrumbs =~ "Add Resource" end - test "renders form", %{ + test "renders form when multi-site resources are disabled", %{ + account: account, + identity: identity, + conn: conn + } do + account = + Fixtures.Accounts.update_account(account, + features: %{ + traffic_filters: false, + multi_site_resources: false + } + ) + + {:ok, lv, _html} = + conn + |> authorize_conn(identity) + |> live(~p"/#{account}/resources/new") + + form = form(lv, "form") + + connection_inputs = [ + "resource[connections][0][enabled]", + "resource[connections][0][gateway_group_id]" + ] + + expected_inputs = + (connection_inputs ++ + [ + "resource[address]", + "resource[address_description]", + "resource[name]", + "resource[type]" + ]) + |> Enum.sort() + + assert find_inputs(form) == expected_inputs + end + + test "renders form when multi-site resources are enabled", %{ account: account, identity: identity, group: group, conn: conn } do + account = + Fixtures.Accounts.update_account(account, + features: %{ + traffic_filters: true, + multi_site_resources: true + } + ) + {:ok, lv, _html} = conn |> authorize_conn(identity) @@ -89,6 +135,43 @@ defmodule Web.Live.Resources.NewTest do assert find_inputs(form) == expected_inputs end + test "renders form when traffic filters are enabled", %{ + account: account, + identity: identity, + conn: conn + } do + account = + Fixtures.Accounts.update_account(account, + features: %{ + traffic_filters: false + } + ) + + {:ok, lv, _html} = + conn + |> authorize_conn(identity) + |> live(~p"/#{account}/resources/new") + + form = form(lv, "form") + + connection_inputs = [ + "resource[connections][0][enabled]", + "resource[connections][0][gateway_group_id]" + ] + + expected_inputs = + (connection_inputs ++ + [ + "resource[address]", + "resource[address_description]", + "resource[name]", + "resource[type]" + ]) + |> Enum.sort() + + assert find_inputs(form) == expected_inputs + end + test "renders form without connections when site is set by query param", %{ account: account, group: group, diff --git a/elixir/mix.lock b/elixir/mix.lock index dc05b03e2..94088b0bc 100644 --- a/elixir/mix.lock +++ b/elixir/mix.lock @@ -1,11 +1,11 @@ %{ "acceptor_pool": {:hex, :acceptor_pool, "1.0.0", "43c20d2acae35f0c2bcd64f9d2bde267e459f0f3fd23dab26485bf518c281b21", [:rebar3], [], "hexpm", "0cbcd83fdc8b9ad2eee2067ef8b91a14858a5883cb7cd800e6fcd5803e158788"}, "argon2_elixir": {:hex, :argon2_elixir, "4.0.0", "7f6cd2e4a93a37f61d58a367d82f830ad9527082ff3c820b8197a8a736648941", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f9da27cf060c9ea61b1bd47837a28d7e48a8f6fa13a745e252556c14f9132c7f"}, - "bandit": {:hex, :bandit, "1.4.2", "a1475c8dcbffd1f43002797f99487a64c8444753ff2b282b52409e279488e1f5", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "3db8bacea631bd926cc62ccad58edfee4252d1b4c5cccbbad9825df2722b884f"}, + "bandit": {:hex, :bandit, "1.5.0", "3bc864a0da7f013ad3713a7f550c6a6ec0e19b8d8715ec678256a0dc197d5539", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "92d18d9a7228a597e0d4661ef69a874ea82d63ff49c7d801a5c68cb18ebbbd72"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "bureaucrat": {:hex, :bureaucrat, "0.2.10", "b0de157dad540e40007b663b683f716ced21f85ff0591093aadb209ad0d967e1", [:mix], [{:inflex, ">= 1.10.0", [hex: :inflex, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.2.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, ">= 1.0.0", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "bc7e5162b911c29c8ebefee87a2c16fbf13821a58f448a8fd024eb6c17fae15c"}, "bypass": {:hex, :bypass, "2.1.0", "909782781bf8e20ee86a9cabde36b259d44af8b9f38756173e8f5e2e1fabb9b1", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "d9b5df8fa5b7a6efa08384e9bbecfe4ce61c77d28a4282f79e02f1ef78d96b80"}, - "castore": {:hex, :castore, "1.0.6", "ffc42f110ebfdafab0ea159cd43d31365fa0af0ce4a02ecebf1707ae619ee727", [:mix], [], "hexpm", "374c6e7ca752296be3d6780a6d5b922854ffcc74123da90f2f328996b962d33a"}, + "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, "chatterbox": {:hex, :ts_chatterbox, "0.15.1", "5cac4d15dd7ad61fc3c4415ce4826fc563d4643dee897a558ec4ea0b1c835c9c", [:rebar3], [{:hpack, "~> 0.3.0", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "4f75b91451338bc0da5f52f3480fa6ef6e3a2aeecfc33686d6b3d0a0948f31aa"}, "cldr_utils": {:hex, :cldr_utils, "2.24.2", "364fa30be55d328e704629568d431eb74cd2f085752b27f8025520b566352859", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "3362b838836a9f0fa309de09a7127e36e67310e797d556db92f71b548832c7cf"}, @@ -46,14 +46,14 @@ "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, - "jose": {:hex, :jose, "1.11.9", "c861eb99d9e9f62acd071dc5a49ffbeab9014e44490cd85ea3e49e3d36184777", [:mix, :rebar3], [], "hexpm", "b5ccc3749d2e1638c26bed806259df5bc9e438797fe60dc71e9fa0716133899b"}, + "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, "junit_formatter": {:hex, :junit_formatter, "3.4.0", "d0e8db6c34dab6d3c4154c3b46b21540db1109ae709d6cf99ba7e7a2ce4b1ac2", [:mix], [], "hexpm", "bb36e2ae83f1ced6ab931c4ce51dd3dbef1ef61bb4932412e173b0cfa259dacd"}, "libcluster": {:hex, :libcluster, "3.3.3", "a4f17721a19004cfc4467268e17cff8b1f951befe428975dd4f6f7b84d927fe0", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7c0a2275a0bb83c07acd17dab3c3bfb4897b145106750eeccc62d302e3bdfee5"}, - "logger_json": {:git, "https://github.com/nebo15/logger_json.git", "1d998ba0172887906b35e7110c74f0d80ac29a56", []}, + "logger_json": {:git, "https://github.com/nebo15/logger_json.git", "29bc59915e108ea21511d4e490db6e088017334c", []}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "mint": {:hex, :mint, "1.5.2", "4805e059f96028948870d23d7783613b7e6b0e2fb4e98d720383852a760067fd", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "d77d9e9ce4eb35941907f1d3df38d8f750c357865353e21d335bdcdf6d892a02"}, + "mint": {:hex, :mint, "1.6.0", "88a4f91cd690508a04ff1c3e28952f322528934be541844d54e0ceb765f01d5e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "3c5ae85d90a5aca0a49c0d8b67360bbe407f3b54f1030a111047ff988e8fefaa"}, "mix_audit": {:hex, :mix_audit, "2.1.3", "c70983d5cab5dca923f9a6efe559abfb4ec3f8e87762f02bab00fa4106d17eda", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.9", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "8c3987100b23099aea2f2df0af4d296701efd031affb08d0746b2be9e35988ec"}, "multipart": {:hex, :multipart, "0.4.0", "634880a2148d4555d050963373d0e3bbb44a55b2badd87fa8623166172e9cda0", [:mix], [{:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "3c5604bc2fb17b3137e5d2abdf5dacc2647e60c5cc6634b102cf1aef75a06f0a"}, "nimble_csv": {:hex, :nimble_csv, "1.2.0", "4e26385d260c61eba9d4412c71cea34421f296d5353f914afe3f2e71cce97722", [:mix], [], "hexpm", "d0628117fcc2148178b034044c55359b26966c6eaa8e2ce15777be3bbc91b12a"},