Packages
livebook
0.6.3
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/user_component.ex
defmodule LivebookWeb.UserComponent do
use LivebookWeb, :live_component
import LivebookWeb.UserHelpers
alias Livebook.Users.User
@impl true
def update(assigns, socket) do
socket = assign(socket, assigns)
user = socket.assigns.user
{:ok, assign(socket, data: user_to_data(user), valid: true, preview_user: user)}
end
defp user_to_data(user) do
%{"name" => user.name || "", "hex_color" => user.hex_color}
end
@impl true
def render(assigns) do
~H"""
<div class="p-6 flex flex-col space-y-5">
<h3 class="text-2xl font-semibold text-gray-800">
User profile
</h3>
<div class="flex justify-center">
<.user_avatar user={@preview_user} class="h-20 w-20" text_class="text-3xl" />
</div>
<.form let={f} for={:data}
phx-submit={@on_save |> JS.push("save")}
phx-change="validate"
phx-target={@myself}
id="user_form"
phx-hook="UserForm">
<div class="flex flex-col space-y-5">
<div>
<div class="input-label">Display name</div>
<%= text_input f, :name, value: @data["name"], class: "input", spellcheck: "false" %>
</div>
<div>
<div class="input-label">Cursor color</div>
<div class="flex space-x-4 items-center">
<div class="border-[3px] rounded-lg p-1 flex justify-center items-center"
style={"border-color: #{@preview_user.hex_color}"}>
<div class="rounded h-5 w-5"
style={"background-color: #{@preview_user.hex_color}"}>
</div>
</div>
<div class="relative grow">
<%= text_input f, :hex_color, value: @data["hex_color"], class: "input", spellcheck: "false", maxlength: 7 %>
<button
class="icon-button absolute right-2 top-1"
type="button"
phx-click="randomize_color"
phx-target={@myself}>
<.remix_icon icon="refresh-line" class="text-xl" />
</button>
</div>
</div>
</div>
<button
class="button-base button-blue flex space-x-1 justify-center items-center"
type="submit"
disabled={not @valid}>
<.remix_icon icon="save-line" />
<span>Save</span>
</button>
</div>
</.form>
</div>
"""
end
@impl true
def handle_event("randomize_color", %{}, socket) do
data = %{
socket.assigns.data
| "hex_color" => User.random_hex_color(except: [socket.assigns.preview_user.hex_color])
}
handle_event("validate", %{"data" => data}, socket)
end
def handle_event("validate", %{"data" => data}, socket) do
{valid, user} =
case User.change(socket.assigns.user, data) do
{:ok, user} -> {true, user}
{:error, _errors, user} -> {false, user}
end
{:noreply, assign(socket, data: data, valid: valid, preview_user: user)}
end
def handle_event("save", %{"data" => data}, socket) do
{:ok, user} = User.change(socket.assigns.user, data)
Livebook.Users.broadcast_change(user)
{:noreply, socket}
end
end