defmodule Oban.Web.Components.Core do use Oban.Web, :html attr :click, :string, required: true attr :danger, :boolean, default: false attr :disabled, :boolean, default: false attr :label, :string, required: true attr :target, :any slot :icon slot :title def action_button(assigns) do class = cond do assigns.disabled -> "text-gray-400" assigns.danger -> "text-red-500 group-hover:text-red-600 hover:bg-gray-100 dark:hover:bg-gray-950" true -> "text-gray-500 group-hover:text-gray-600 hover:bg-gray-100 dark:hover:bg-gray-950" end assigns = assign(assigns, :class, class) ~H""" """ end slot :inner_block, required: true attr :name, :string, required: true attr :options, :list, required: true attr :selected, :any, required: true attr :title, :string, required: true attr :disabled, :boolean, default: false attr :target, :any, default: "myself" def dropdown_button(assigns) do ~H"""
""" end attr :name, :any, required: true attr :value, :any, required: true attr :selected, :any, required: true attr :target, :any defp dropdown_option(assigns) do class = if assigns.selected == assigns.value do "text-blue-500 dark:text-blue-400" else "text-gray-500 dark:text-gray-400 " end assigns = assign(assigns, :class, class) ~H"""
  • <%= if to_string(@value) == to_string(@selected) do %> <% else %> <% end %> {@value |> to_string() |> String.replace("_", " ")}
  • """ end attr :checked, :boolean, default: false attr :click, :string, required: true attr :myself, :any, required: true attr :value, :string, required: true def row_checkbox(assigns) do style = if assigns.checked do "border-blue-500 bg-blue-500" else "border-gray-400 dark:border-gray-600 group-hover:bg-gray-400 dark:group-hover:bg-gray-600" end assigns = assign(assigns, :style, style) ~H""" """ end attr :checked, :atom, required: true attr :click, :string, required: true attr :myself, :any, required: true def all_checkbox(assigns) do style = if assigns.checked in [:all, :some] do "border-blue-500 bg-blue-500" else "border-gray-400 dark:border-gray-600 group-hover:bg-gray-400 dark:group-hover:bg-gray-600" end assigns = assign(assigns, :style, style) ~H""" """ end @doc """ A status badge with icon that expands to show label on hover. """ attr :icon, :string, required: true attr :id, :string, default: nil attr :label, :string, required: true def status_badge(assigns) do ~H"""
    <.badge_icon name={@icon} /> {@label}
    """ end defp badge_icon(%{name: "camera"} = assigns), do: ~H[] defp badge_icon(%{name: "life_buoy"} = assigns), do: ~H[] defp badge_icon(%{name: "lock_closed"} = assigns), do: ~H[] defp badge_icon(%{name: "signal"} = assigns), do: ~H[] defp badge_icon(%{name: "sparkles"} = assigns), do: ~H[] defp badge_icon(%{name: "table_cells"} = assigns), do: ~H[] defp badge_icon(%{name: "square_2x2"} = assigns), do: ~H[] defp badge_icon(%{name: "rectangle_group"} = assigns), do: ~H[] defp badge_icon(%{name: "user_group"} = assigns), do: ~H[] defp badge_icon(%{name: "link"} = assigns), do: ~H[] defp badge_icon(%{name: "power"} = assigns), do: ~H[] defp badge_icon(%{name: "pause_circle"} = assigns), do: ~H[] defp badge_icon(%{name: "play_pause_circle"} = assigns), do: ~H[] @doc """ An icon-only button that expands to show label on hover. Supports disabled state. """ attr :id, :string, required: true attr :icon, :string, required: true attr :label, :string, required: true attr :color, :string, required: true attr :disabled, :boolean, default: false attr :confirm, :string, default: nil attr :tooltip, :string, default: nil attr :rest, :global def icon_button(assigns) do color_classes = case {assigns.color, assigns.disabled} do {_, true} -> "text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 border-gray-200 dark:border-gray-700 cursor-not-allowed" {"yellow", false} -> "text-gray-600 dark:text-gray-400 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-700 cursor-pointer hover:text-yellow-600 hover:border-yellow-600" {"blue", false} -> "text-gray-600 dark:text-gray-400 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-700 cursor-pointer hover:text-blue-500 hover:border-blue-600" {"red", false} -> "text-gray-600 dark:text-gray-400 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-700 cursor-pointer hover:text-red-500 hover:border-red-600" {"violet", false} -> "text-gray-600 dark:text-gray-400 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-700 cursor-pointer hover:text-violet-500 hover:border-violet-600" end icon_color = if assigns.disabled do "text-gray-400 dark:text-gray-500" else case assigns.color do "yellow" -> "text-gray-500 group-hover:text-yellow-500" "blue" -> "text-gray-500 group-hover:text-blue-500" "red" -> "text-gray-500 group-hover:text-red-500" "violet" -> "text-gray-500 group-hover:text-violet-500" end end assigns = assign(assigns, color_classes: color_classes, icon_color: icon_color) ~H""" """ end defp button_icon(%{name: "arrow_path"} = assigns), do: ~H[] defp button_icon(%{name: "pause_circle"} = assigns), do: ~H[] defp button_icon(%{name: "pencil_square"} = assigns), do: ~H[] defp button_icon(%{name: "play_circle"} = assigns), do: ~H[] defp button_icon(%{name: "trash"} = assigns), do: ~H[] defp button_icon(%{name: "x_circle"} = assigns), do: ~H[] # Sparkline attr :id, :string, required: true attr :history, :map, required: true attr :max_value, :integer, default: nil attr :bar_width, :integer, default: 4 attr :count, :integer, default: 60 attr :gap, :integer, default: 1 attr :height, :integer, default: 16 attr :class, :string, default: nil def sparkline(assigns) do history = assigns.history count = assigns.count bar_width = assigns.bar_width gap = assigns.gap height = assigns.height max_index = count - 1 max_value = if assigns.max_value do max(assigns.max_value, 1) else history |> Map.values() |> Enum.reduce(1, fn %{count: c}, acc -> max(c, acc) end) end now = System.system_time(:millisecond) {bars, tooltip_data} = for slot <- 0..max_index, reduce: {[], []} do {bars_acc, tool_acc} -> index = max_index - slot timestamp = now - index * 5 * 1000 x = slot * (bar_width + gap) case Map.get(history, index) do %{count: c} -> bar_height = min(c / max_value, 1.0) * height bar = %{x: x, height: max(bar_height, 0)} tooltip = %{timestamp: timestamp, count: c} {[bar | bars_acc], [tooltip | tool_acc]} nil -> tooltip = %{timestamp: timestamp, count: 0} {bars_acc, [tooltip | tool_acc]} end end bars = Enum.reverse(bars) tooltip_data = Enum.reverse(tooltip_data) placeholders = for slot <- 0..max_index do %{x: slot * (bar_width + gap)} end width = count * (bar_width + gap) assigns = assigns |> assign(bars: bars, placeholders: placeholders, width: width) |> assign(tooltip_data: tooltip_data) ~H""" """ end end