summaryrefslogtreecommitdiff
path: root/src/flagd-ui/lib/flagd_ui_web/live
diff options
context:
space:
mode:
authorSaumit <justsaumit@protonmail.com>2025-09-27 02:14:26 +0530
committerSaumit <justsaumit@protonmail.com>2025-09-27 02:14:26 +0530
commit82e03978b89938219958032efb1448cc76baa181 (patch)
tree626f3e54d52ecd49be0ed3bee30abacc0453d081 /src/flagd-ui/lib/flagd_ui_web/live
Initial snapshot - OpenTelemetry demo 2.1.3 -f
Diffstat (limited to 'src/flagd-ui/lib/flagd_ui_web/live')
-rw-r--r--src/flagd-ui/lib/flagd_ui_web/live/advanced_editor.ex92
-rw-r--r--src/flagd-ui/lib/flagd_ui_web/live/dashboard.ex66
2 files changed, 158 insertions, 0 deletions
diff --git a/src/flagd-ui/lib/flagd_ui_web/live/advanced_editor.ex b/src/flagd-ui/lib/flagd_ui_web/live/advanced_editor.ex
new file mode 100644
index 0000000..fbecaa8
--- /dev/null
+++ b/src/flagd-ui/lib/flagd_ui_web/live/advanced_editor.ex
@@ -0,0 +1,92 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+defmodule FlagdUiWeb.AdvancedEditor do
+ use FlagdUiWeb, :live_view
+
+ alias FlagdUiWeb.CoreComponents
+ alias FlagdUiWeb.Components.Navbar
+
+ def mount(_, _, socket) do
+ state = GenServer.call(Storage, :read)
+ content = Jason.encode!(state, pretty: true)
+
+ {:ok,
+ socket
+ |> assign(content: content)
+ |> assign(unsaved_changes: false)}
+ end
+
+ def render(assigns) do
+ ~H"""
+ <div class="relative min-h-screen">
+ <Navbar.navbar mode="advanced" />
+
+ <CoreComponents.flash kind={:error} flash={@flash} />
+ <CoreComponents.flash kind={:info} flash={@flash} />
+
+ <div class="container mx-auto px-4 py-8">
+ <.form for={%{}}>
+ <textarea
+ name="content"
+ type="textarea"
+ class="mb-4 h-48 w-full bg-gray-700 p-3 text-sm text-gray-300 focus:border-blue-500 focus:outline-none sm:h-64 md:h-80 lg:h-96 xl:h-[32rem] 2xl:h-[48rem]"
+ cols={200}
+ phx-change="edit"
+ >
+ {Phoenix.HTML.Form.normalize_value("textarea", @content)}
+ </textarea>
+ <div>
+ <button
+ type="button"
+ class="rounded bg-blue-500 px-8 py-4 font-medium text-white transition-colors duration-200 hover:bg-blue-600"
+ phx-click="save"
+ >
+ Save
+ </button>
+ <p :if={@unsaved_changes} class="text-red-600">Unsaved changes</p>
+ </div>
+ </.form>
+ </div>
+ </div>
+ """
+ end
+
+ def handle_event("edit", payload, socket) do
+ %{"content" => content} = payload
+
+ {:noreply,
+ socket
+ |> assign(content: content)
+ |> assign(unsaved_changes: true)}
+ end
+
+ def handle_event(
+ "save",
+ _,
+ %{
+ assigns: %{
+ content: content
+ }
+ } = socket
+ ) do
+ new_socket =
+ case Jason.decode(content) do
+ {:ok, _} ->
+ trimmed_content = String.trim(content)
+
+ GenServer.cast(Storage, {:replace, trimmed_content})
+
+ socket
+ |> assign(unsaved_changes: false)
+ |> assign(content: trimmed_content)
+ |> clear_flash()
+ |> put_flash(:info, "Saved!")
+
+ {:error, _} ->
+ put_flash(socket, :error, "Invalid JSON")
+ end
+
+ {:noreply, new_socket}
+ end
+end
diff --git a/src/flagd-ui/lib/flagd_ui_web/live/dashboard.ex b/src/flagd-ui/lib/flagd_ui_web/live/dashboard.ex
new file mode 100644
index 0000000..cacd1d8
--- /dev/null
+++ b/src/flagd-ui/lib/flagd_ui_web/live/dashboard.ex
@@ -0,0 +1,66 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+defmodule FlagdUiWeb.Dashboard do
+ use FlagdUiWeb, :live_view
+
+ alias FlagdUiWeb.CoreComponents
+ alias FlagdUiWeb.Components.Navbar
+
+ def mount(_, _, socket) do
+ %{"flags" => flags} = GenServer.call(Storage, :read)
+ {:ok, socket |> assign(:flags, flags)}
+ end
+
+ def render(assigns) do
+ ~H"""
+ <div class="relative min-h-screen">
+ <Navbar.navbar />
+
+ <CoreComponents.flash kind={:error} flash={@flash} />
+ <CoreComponents.flash kind={:info} flash={@flash} />
+
+ <.form for={@flags}>
+ <div class="container mx-auto px-4 py-8">
+ <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
+ <div
+ :for={{name, data} <- @flags}
+ class="mb-4 flex flex-auto flex-col justify-between rounded-md bg-gray-800 p-6 text-gray-300 shadow-md"
+ >
+ <div>
+ <p class="mb-4 text-lg font-semibold">{name}</p>
+ <p class="-4 text-sm">{data["description"]}</p>
+ </div>
+ <div>
+ <div class="flex items-center justify-between">
+ <CoreComponents.input
+ name={name}
+ type="select"
+ options={get_variants(data)}
+ value={data["defaultVariant"]}
+ phx-change="flag_changed"
+ />
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </.form>
+ </div>
+ """
+ end
+
+ def handle_event("flag_changed", payload, socket) do
+ %{"_target" => [target]} = payload
+ variant = payload[target]
+
+ GenServer.cast(Storage, {:write, target, variant})
+
+ new_socket = put_flash(socket, :info, "Saved: #{target}")
+
+ {:noreply, new_socket}
+ end
+
+ defp get_variants(%{"variants" => variants}), do: Enum.map(variants, fn {key, _} -> key end)
+ defp get_variants(_), do: []
+end