Skip to content

Commit

Permalink
New UI: Consistently style buttons and button links (#1818)
Browse files Browse the repository at this point in the history
And create a component just for icons
  • Loading branch information
joshk authored Jan 23, 2025
1 parent dd79ab4 commit 7374eda
Show file tree
Hide file tree
Showing 17 changed files with 248 additions and 271 deletions.
10 changes: 0 additions & 10 deletions assets/ui-rework/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,6 @@
font-size: 12px;
}

.action-button {
@apply border border-base-600 bg-base-800 text-base-300;
display: flex;
gap: 8px;
padding: 6px 12px;
justify-content: center;
align-items: center;
border-radius: 4px;
}

.pager-button {
@apply rounded-sm px-[12px] py-[6px];
font-size: 14px;
Expand Down
6 changes: 6 additions & 0 deletions lib/nerves_hub_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ defmodule NervesHubWeb do

import NervesHubWeb.Helpers.Authorization

import NervesHubWeb.Components.Icons
import NervesHubWeb.CoreComponents, only: [button: 1, input: 1, core_label: 1, error: 1]

# Shortcut for generating JS commands
alias Phoenix.LiveView.JS

Expand Down Expand Up @@ -137,6 +140,9 @@ defmodule NervesHubWeb do

import NervesHubWeb.Helpers.Authorization

import NervesHubWeb.Components.Icons
import NervesHubWeb.CoreComponents, only: [button: 1, input: 1, core_label: 1, error: 1]

def ok(socket), do: {:ok, socket}

def noreply(socket), do: {:noreply, socket}
Expand Down
62 changes: 61 additions & 1 deletion lib/nerves_hub_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,69 @@ defmodule NervesHubWeb.CoreComponents do
<.button>Send!</.button>
<.button phx-click="go" class="ml-2">Send!</.button>
"""
attr(:style, :string, default: "secondary")
attr(:type, :string, default: nil)
attr(:class, :string, default: nil)
attr(:rest, :global, include: ~w(disabled form name value))
attr(:rest, :global, include: ~w(disabled form name value href navigate download))

slot(:inner_block, required: true)

def button(%{type: "link", style: "secondary"} = assigns) do
~H"""
<.link
class={[
"phx-submit-loading:opacity-75 flex items-center justify-center px-3 py-1.5 gap-2 rounded",
"bg-zinc-800 hover:bg-zinc-700 active:bg-indigo-500 disabled:bg-zinc-800",
"border rounded border-zinc-600 active:border-indigo-500",
"stroke-zinc-400 active:stroke-zinc-100 disabled:stroke-zinc-600",
"text-sm font-medium text-zinc-300 hover:text-neutral-50 active:text-neutral-50 disabled:text-zinc-500",
@class
]}
{@rest}
>
{render_slot(@inner_block)}
</.link>
"""
end

def button(%{style: "primary"} = assigns) do
~H"""
<button
type={@type}
class={[
"phx-submit-loading:opacity-75 flex px-3 py-1.5 gap-2 rounded",
"bg-indigo-500 hover:bg-indigo-400 active:bg-indigo-600 disabled:bg-zinc-800",
"disabled:bg-zinc-800 disabled:border disabled:rounded disabled:border-zinc-600",
"stroke-zinc-50 disabled:stroke-zinc-500",
"text-sm font-medium text-zinc-50 disabled:text-zinc-500",
@class
]}
{@rest}
>
{render_slot(@inner_block)}
</button>
"""
end

def button(%{style: "secondary"} = assigns) do
~H"""
<button
type={@type}
class={[
"phx-submit-loading:opacity-75 flex px-3 py-1.5 gap-2 rounded",
"bg-zinc-800 hover:bg-zinc-700 active:bg-indigo-500 disabled:bg-zinc-800",
"border rounded border-zinc-600 active:border-indigo-500",
"stroke-zinc-400 active:stroke-zinc-100 disabled:stroke-zinc-600",
"text-sm font-medium text-zinc-300 hover:text-neutral-50 active:text-neutral-50 disabled:text-zinc-500",
@class
]}
{@rest}
>
{render_slot(@inner_block)}
</button>
"""
end

def button(assigns) do
~H"""
<button
Expand Down Expand Up @@ -407,6 +464,9 @@ defmodule NervesHubWeb.CoreComponents do
"""
end

# TODO: can be removed when we remove our use of Phoenix.HTML.Form
def core_label(assigns), do: label(assigns)

@doc """
Generates a generic error message.
"""
Expand Down
51 changes: 19 additions & 32 deletions lib/nerves_hub_web/components/deployment_page/settings.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
<div class="flex p-6 gap-6">
<div class="w-1/2 flex flex-col gap-6">
<NervesHubWeb.CoreComponents.input field={@form[:name]} label="Name" placeholder="Production" />
<.input field={@form[:name]} label="Name" placeholder="Production" />
</div>
</div>
</div>
Expand All @@ -48,7 +48,7 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
<div class="flex flex-col p-6 gap-6">
<div class="w-1/2 flex flex-col gap-6">
<NervesHubWeb.CoreComponents.input
<.input
field={@form[:firmware_id]}
type="select"
options={firmware_dropdown_options(@firmwares)}
Expand All @@ -58,7 +58,7 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
</div>
<div class="w-1/2 flex flex-col gap-6">
<NervesHubWeb.CoreComponents.input
<.input
field={@form[:archive_id]}
type="select"
options={archive_dropdown_options(@archives)}
Expand All @@ -85,10 +85,10 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
</p>
</div>
<div class="w-1/2">
<NervesHubWeb.CoreComponents.input field={@form[:tags]} value={tags_to_string(@form[:conditions])} label="Tag(s) distributed to" placeholder="eg. batch-123" />
<.input field={@form[:tags]} value={tags_to_string(@form[:conditions])} label="Tag(s) distributed to" placeholder="eg. batch-123" />
</div>
<div class="w-1/2">
<NervesHubWeb.CoreComponents.input field={@form[:version]} value={@form[:conditions].value["version"]} label="Version requirement" placeholder="eg. 1.2.3" />
<.input field={@form[:version]} value={@form[:conditions].value["version"]} label="Version requirement" placeholder="eg. 1.2.3" />
</div>
</div>
</div>
Expand All @@ -100,7 +100,7 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
<div class="flex flex p-6 gap-6">
<div class="w-1/2 flex flex-col gap-6">
<NervesHubWeb.CoreComponents.input
<.input
field={@form[:concurrent_updates]}
label="Concurrent Device Updates"
type="number"
Expand All @@ -109,7 +109,7 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
</div>
<div class="w-1/2 flex flex-col gap-6">
<NervesHubWeb.CoreComponents.input
<.input
field={@form[:inflight_update_expiration_minutes]}
label="Minutes Before Expiring Updates"
type="number"
Expand All @@ -123,7 +123,7 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
<div class="w-1/2">
<div phx-feedback-for={@form[:failure_rate].name}>
<span class="flex items-end">
<NervesHubWeb.CoreComponents.label for={@form[:failure_rate_amount].id}>Failure rate</NervesHubWeb.CoreComponents.label>
<.core_label for={@form[:failure_rate_amount].id}>Failure rate</.core_label>
</span>
<div class="flex items-center gap-2">
<input
Expand Down Expand Up @@ -163,15 +163,15 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
</div>
<div class="w-1/2">
<NervesHubWeb.CoreComponents.input field={@form[:failure_threshold]} label="Failure threshold" type="number" hint={help_message_for(:failure_threshold)} />
<.input field={@form[:failure_threshold]} label="Failure threshold" type="number" hint={help_message_for(:failure_threshold)} />
</div>
</div>
<div class="flex gap-6">
<div class="w-1/2">
<div phx-feedback-for={@form[:device_failure_rate_amount].name}>
<span class="flex items-end">
<NervesHubWeb.CoreComponents.label for={@form[:device_failure_rate_amount].id}>Device failure rate</NervesHubWeb.CoreComponents.label>
<.core_label for={@form[:device_failure_rate_amount].id}>Device failure rate</.core_label>
</span>
<div class="flex items-center gap-2">
<input
Expand Down Expand Up @@ -204,22 +204,20 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
<div class="flex flex-col gap-1 text-xs text-zinc-400 pt-1">
Maximum number of device failures within X seconds a device can have for this deployment before being marked unhealthy
</div>
<NervesHubWeb.CoreComponents.error :for={
msg <- Enum.map(@form[:device_failure_rate_amount].errors ++ @form[:device_failure_rate_seconds].errors, &NervesHubWeb.CoreComponents.translate_error(&1))
}>
<.error :for={msg <- Enum.map(@form[:device_failure_rate_amount].errors ++ @form[:device_failure_rate_seconds].errors, &NervesHubWeb.CoreComponents.translate_error(&1))}>
{msg}
</NervesHubWeb.CoreComponents.error>
</.error>
</div>
</div>
<div class="w-1/2">
<NervesHubWeb.CoreComponents.input field={@form[:device_failure_threshold]} label="Device failure threshold" type="number" hint={help_message_for(:device_failure_threshold)} />
<.input field={@form[:device_failure_threshold]} label="Device failure threshold" type="number" hint={help_message_for(:device_failure_threshold)} />
</div>
</div>
<div class="flex gap-6">
<div class="w-1/2">
<NervesHubWeb.CoreComponents.input field={@form[:penalty_timeout_minutes]} label="Device penalty box timeout minutes" type="number" hint={help_message_for(:penalty_timeout_minutes)} />
<.input field={@form[:penalty_timeout_minutes]} label="Device penalty box timeout minutes" type="number" hint={help_message_for(:penalty_timeout_minutes)} />
</div>
</div>
</div>
Expand All @@ -232,7 +230,7 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
<div class="flex flex-col p-6 gap-6">
<div class="w-2/3 flex flex-col gap-6">
<NervesHubWeb.CoreComponents.input field={@form[:connecting_code]} type="textarea" rows={8} label="Run this code when the device first connects to the console.">
<.input field={@form[:connecting_code]} type="textarea" rows={8} label="Run this code when the device first connects to the console.">
<:rich_hint>
<p>
Make sure this is valid Elixir and will not crash the device.
Expand All @@ -241,27 +239,16 @@ defmodule NervesHubWeb.Components.DeploymentPage.Settings do
This will run before device specific first connect code.
</p>
</:rich_hint>
</NervesHubWeb.CoreComponents.input>
</.input>
</div>
</div>
</div>
<div class="w-2/3 flex flex-col bg-zinc-900 border border-zinc-700 rounded">
<div class="flex items-center p-6 gap-6 border-t border-zinc-700">
<div>
<button class="flex px-3 py-1.5 gap-2 rounded bg-zinc-800 border border-zinc-600" type="submit">
<svg class="size-5" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.66671 16.6667H5.00004C4.07957 16.6667 3.33337 15.9205 3.33337 15V5.00004C3.33337 4.07957 4.07957 3.33337 5.00004 3.33337H12.643C13.085 3.33337 13.509 3.50897 13.8215 3.82153L16.1786 6.17855C16.4911 6.49111 16.6667 6.91504 16.6667 7.35706V15C16.6667 15.9205 15.9205 16.6667 15 16.6667H13.3334M6.66671 16.6667V12.5H13.3334V16.6667M6.66671 16.6667H13.3334M6.66671 6.66671V9.16671H9.16671V6.66671H6.66671Z"
stroke="#A1A1AA"
stroke-width="1.2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="text-sm font-medium text-zinc-300">Save changes</span>
</button>
</div>
<.button style="secondary" type="submit">
<.icon name="save" /> Save changes
</.button>
</div>
</div>
</.form>
Expand Down
33 changes: 12 additions & 21 deletions lib/nerves_hub_web/components/device_page/details.ex
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ defmodule NervesHubWeb.Components.DevicePage.Details do
</button>
</div>
<div :if={@device.status == :registered && @device.deployment_id} class="flex pt-2 px-4 pb-6 gap-4 items-center">
<span class="text-sm text-nerves-gray-500">Note: Device will be removed from the deployment upon connection if the aarch and platform doesn't match.</span>
<span class="text-sm text-nerves-gray-500">Please note: The device will be removed from the deployment upon connection if the aarch and platform don't match.</span>
</div>
<div :if={is_nil(@device.deployment) && Enum.any?(@deployments)} class="flex p-4 gap-4 items-center border-t border-zinc-700">
Expand All @@ -308,13 +308,9 @@ defmodule NervesHubWeb.Components.DevicePage.Details do
<option :for={deployment <- @deployments} value={deployment.id}>{deployment.name} - ({deployment.firmware.platform}, {deployment.firmware.architecture})</option>
</select>
</div>
<button
class="box-content h-5 py-1.5 px-3 rounded border border-base-600 bg-zinc-800 text-sm font-medium text-zinc-300 disabled:text-zinc-500"
aria-label="Add to deployment"
data-confirm="Are you sure you want to add the device to the deployment?"
>
<.button type="submit" aria-label="Add to deployment" data-confirm="Are you sure you want to add the device to the deployment?">
Add to deployment
</button>
</.button>
</form>
<div>
<svg class="w-5 h-5" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
Expand All @@ -335,16 +331,15 @@ defmodule NervesHubWeb.Components.DevicePage.Details do
<span class="text-sm text-nerves-gray-500">An update is available in the assigned deployment.</span>
</div>
<button
<.button
phx-target={@myself}
phx-submit="push-available-update"
class="box-content h-5 py-1.5 px-3 mr-9 rounded border border-base-600 bg-zinc-800 text-sm font-medium text-zinc-300 disabled:text-zinc-500"
aria-label="Send available update"
data-confirm="Are you sure?"
data-confirm="Are you sure you want to skip the queue?"
disabled={disconnected?(@device_connection)}
>
Skip the queue
</button>
</.button>
</div>
<div class="flex p-4 gap-4 items-center border-t border-zinc-700">
Expand All @@ -359,14 +354,10 @@ defmodule NervesHubWeb.Components.DevicePage.Details do
<option :for={firmware <- @firmwares} value={firmware.uuid}>{firmware.version}</option>
</select>
</div>
<button
class="box-content h-5 py-1.5 px-3 rounded border border-base-600 bg-zinc-800 text-sm font-medium text-zinc-300 disabled:text-zinc-500"
disabled={disconnected?(@device_connection)}
aria-label="Send firmware update"
data-confirm="Are you sure?"
>
<.button type="submit" disabled={disconnected?(@device_connection)} aria-label="Send firmware update" data-confirm="Are you sure you want to send this firmware to the device?">
Send update
</button>
</.button>
</form>
<div>
<svg class="w-5 h-5" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
Expand Down Expand Up @@ -434,9 +425,9 @@ defmodule NervesHubWeb.Components.DevicePage.Details do
</div>
<div class="flex p-4 gap-4 items-center border-t border-zinc-700">
<.link navigate={~p"/org/#{@org.name}/#{@product.name}/scripts"} class="box-content h-5 py-1.5 px-3 rounded border border-base-600 bg-zinc-800 text-sm font-medium text-zinc-300">
Add a support script
</.link>
<.button type="link" navigate={~p"/org/#{@org.name}/#{@product.name}/scripts/new"} aria-label="Add a support script">
<.icon name="add" />Add a support script
</.button>
</div>
</div>
</div>
Expand Down
23 changes: 6 additions & 17 deletions lib/nerves_hub_web/components/device_page/settings.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,9 @@ defmodule NervesHubWeb.Components.DevicePage.Settings do
<div class="flex flex-col w-full bg-zinc-900 border border-zinc-700 rounded">
<div class="flex justify-between items-center h-14 px-4 border-b border-zinc-700">
<div class="text-base text-neutral-50 font-medium">General settings</div>
<div>
<button class="flex px-3 py-1.5 gap-2 rounded bg-zinc-800 border border-zinc-600" type="submit">
<svg class="w-5 h-5" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.66671 16.6667H5.00004C4.07957 16.6667 3.33337 15.9205 3.33337 15V5.00004C3.33337 4.07957 4.07957 3.33337 5.00004 3.33337H12.643C13.085 3.33337 13.509 3.50897 13.8215 3.82153L16.1786 6.17855C16.4911 6.49111 16.6667 6.91504 16.6667 7.35706V15C16.6667 15.9205 15.9205 16.6667 15 16.6667H13.3334M6.66671 16.6667V12.5H13.3334V16.6667M6.66671 16.6667H13.3334M6.66671 6.66671V9.16671H9.16671V6.66671H6.66671Z"
stroke="#A1A1AA"
stroke-width="1.2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="text-sm font-medium text-zinc-300">Save changes</span>
</button>
</div>
<.button style="secondary" type="submit">
<.icon name="save" /> Save changes
</.button>
</div>
<div class="flex p-6 gap-6">
<div class="w-1/2 flex flex-col gap-6">
Expand All @@ -79,13 +68,13 @@ defmodule NervesHubWeb.Components.DevicePage.Settings do
</p>
</div> --%>
<NervesHubWeb.CoreComponents.input field={@settings_form[:description]} label="Description" placeholder="eg. sensor hub at customer X" />
<.input field={@settings_form[:description]} label="Description" placeholder="eg. sensor hub at customer X" />
<NervesHubWeb.CoreComponents.input field={@settings_form[:tags]} value={tags_to_string(@settings_form[:tags])} label="Tags" placeholder="eg. batch-123" />
<.input field={@settings_form[:tags]} value={tags_to_string(@settings_form[:tags])} label="Tags" placeholder="eg. batch-123" />
</div>
<div class="w-1/2 flex flex-col gap-2">
<NervesHubWeb.CoreComponents.input field={@settings_form[:first_connect_code]} label="First connect code" type="textarea" rows="10" />
<.input field={@settings_form[:first_connect_code]} label="First connect code" type="textarea" rows="10" />
<div class="text-xs tracking-wide text-zinc-400">Make sure this is valid Elixir and will not crash the device</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 7374eda

Please sign in to comment.