Skip to content

Commit

Permalink
Move app settings to a modal and add explanations
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatanklosko committed May 19, 2023
1 parent 52df405 commit ed12966
Show file tree
Hide file tree
Showing 6 changed files with 362 additions and 299 deletions.
54 changes: 37 additions & 17 deletions lib/livebook_web/components/form_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil
attr :class, :string, default: nil

attr :rest, :global, include: ~w(autocomplete readonly disabled)
Expand All @@ -22,7 +23,7 @@ defmodule LivebookWeb.FormComponents do
assigns = assigns_from_field(assigns)

~H"""
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors}>
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors} help={@help}>
<input
type="text"
name={@name}
Expand All @@ -44,6 +45,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :resizable, :boolean, default: false

Expand All @@ -53,7 +55,7 @@ defmodule LivebookWeb.FormComponents do
assigns = assigns_from_field(assigns)

~H"""
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors}>
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors} help={@help}>
<textarea
id={@id || @name}
name={@name}
Expand Down Expand Up @@ -91,6 +93,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil
attr :class, :string, default: nil

attr :rest, :global, include: ~w(autocomplete readonly disabled)
Expand All @@ -99,7 +102,7 @@ defmodule LivebookWeb.FormComponents do
assigns = assigns_from_field(assigns)

~H"""
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors}>
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors} help={@help}>
<.with_password_toggle id={@id <> "-toggle"}>
<input
type="password"
Expand All @@ -123,6 +126,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :randomize, JS, default: %JS{}
attr :rest, :global
Expand All @@ -131,7 +135,7 @@ defmodule LivebookWeb.FormComponents do
assigns = assigns_from_field(assigns)

~H"""
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors}>
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors} help={@help}>
<div class="flex space-x-4 items-center">
<div
class="border-[3px] rounded-lg p-1 flex justify-center items-center"
Expand Down Expand Up @@ -168,11 +172,11 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :disabled, :boolean, default: false
attr :checked_value, :string, default: "true"
attr :unchecked_value, :string, default: "false"
attr :tooltip, :string, default: nil

attr :rest, :global

Expand All @@ -182,12 +186,9 @@ defmodule LivebookWeb.FormComponents do
~H"""
<div phx-feedback-for={@name} class={[@errors != [] && "show-errors"]}>
<div class="flex items-center gap-1 sm:gap-3 justify-between">
<span
:if={@label}
class={["text-gray-700", @tooltip && "tooltip top"]}
data-tooltip={@tooltip}
>
<span :if={@label} class="text-gray-700 flex gap-1 items-center">
<%= @label %>
<.help :if={@help} text={@help} />
</span>
<label class={[
"relative inline-block w-14 h-7 select-none",
Expand Down Expand Up @@ -227,6 +228,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :checked_value, :string, default: "true"
attr :unchecked_value, :string, default: "false"
Expand All @@ -249,7 +251,10 @@ defmodule LivebookWeb.FormComponents do
checked={to_string(@value) == @checked_value}
{@rest}
/>
<span :if={@label} class="text-gray-700"><%= @label %></span>
<span :if={@label} class="text-gray-700 flex gap-1 items-center">
<%= @label %>
<.help :if={@help} text={@help} />
</span>
</label>
<.error :for={msg <- @errors}><%= msg %></.error>
</div>
Expand All @@ -265,6 +270,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :options, :list, default: [], doc: "a list of `{value, description}` tuples"

Expand All @@ -275,7 +281,7 @@ defmodule LivebookWeb.FormComponents do

~H"""
<div phx-feedback-for={@name} class={[@errors != [] && "show-errors"]}>
<.label :if={@label} for={@id}><%= @label %></.label>
<.label :if={@label} for={@id} help={@help}><%= @label %></.label>
<div class="flex gap-4 text-gray-600">
<label :for={{value, description} <- @options} class="flex items-center gap-2 cursor-pointer">
<input
Expand Down Expand Up @@ -304,6 +310,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :options, :list, default: [], doc: "a list of `{value, description}` tuples"
attr :full_width, :boolean, default: false
Expand All @@ -315,7 +322,7 @@ defmodule LivebookWeb.FormComponents do

~H"""
<div phx-feedback-for={@name} class={[@errors != [] && "show-errors"]}>
<.label :if={@label} for={@id}><%= @label %></.label>
<.label :if={@label} for={@id} help={@help}><%= @label %></.label>
<div class="flex">
<label
:for={{value, description} <- @options}
Expand Down Expand Up @@ -352,14 +359,15 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :rest, :global

def emoji_field(assigns) do
assigns = assigns_from_field(assigns)

~H"""
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors}>
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors} help={@help}>
<div class="flex border bg-gray-50 rounded-lg space-x-4 items-center">
<div id={"#{@id}-picker"} class="flex w-full" phx-hook="EmojiPicker">
<div class="grow p-1 pl-3">
Expand Down Expand Up @@ -396,6 +404,7 @@ defmodule LivebookWeb.FormComponents do
attr :value, :any
attr :errors, :list, default: []
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
attr :help, :string, default: nil

attr :options, :list, default: []
attr :prompt, :string, default: nil
Expand All @@ -406,7 +415,7 @@ defmodule LivebookWeb.FormComponents do
assigns = assigns_from_field(assigns)

~H"""
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors}>
<.field_wrapper id={@id} name={@name} label={@label} errors={@errors} help={@help}>
<select id={@id} name={@name} class="input" {@rest}>
<option :if={@prompt} value="" disabled selected><%= @prompt %></option>
<%= Phoenix.HTML.Form.options_for_select(@options, @value) %>
Expand Down Expand Up @@ -440,12 +449,13 @@ defmodule LivebookWeb.FormComponents do
attr :name, :any, required: true
attr :label, :string, required: true
attr :errors, :list, required: true
attr :help, :string, required: true
slot :inner_block, required: true

defp field_wrapper(assigns) do
~H"""
<div phx-feedback-for={@name} class={[@errors != [] && "show-errors"]}>
<.label :if={@label} for={@id}><%= @label %></.label>
<.label :if={@label} for={@id} help={@help}><%= @label %></.label>
<%= render_slot(@inner_block) %>
<.error :for={msg <- @errors}><%= msg %></.error>
</div>
Expand All @@ -456,12 +466,14 @@ defmodule LivebookWeb.FormComponents do
Renders a label.
"""
attr :for, :string, default: nil
attr :help, :string, default: nil
slot :inner_block, required: true

def label(assigns) do
~H"""
<label for={@for} class="mb-1 block text-sm text-gray-800 font-medium">
<label for={@for} class="mb-1 block text-sm text-gray-800 font-medium flex items-center gap-1">
<%= render_slot(@inner_block) %>
<.help :if={@help} text={@help} />
</label>
"""
end
Expand All @@ -479,6 +491,14 @@ defmodule LivebookWeb.FormComponents do
"""
end

defp help(assigns) do
~H"""
<span class="cursor-pointer tooltip top" data-tooltip={@text}>
<.remix_icon icon="question-line" class="text-sm leading-none" />
</span>
"""
end

@doc """
Renders a wrapper around password input with an added visibility
toggle button.
Expand Down
40 changes: 40 additions & 0 deletions lib/livebook_web/live/session_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,21 @@ defmodule LivebookWeb.SessionLive do
/>
</.modal>
<.modal
:if={@live_action == :app_settings}
id="app-settings-modal"
show
width={:medium}
patch={@self_path}
>
<.live_component
module={LivebookWeb.SessionLive.AppSettingsComponent}
id="app-settings"
session={@session}
settings={@data_view.app_settings}
/>
</.modal>
<.modal
:if={@live_action == :shortcuts}
id="shortcuts-modal"
Expand Down Expand Up @@ -1233,6 +1248,31 @@ defmodule LivebookWeb.SessionLive do
{:noreply, socket}
end

def handle_event("deploy_app", %{}, socket) do
on_confirm = fn socket ->
Livebook.Session.deploy_app(socket.assigns.session.pid)
socket
end

data = socket.private.data
slug = data.notebook.app_settings.slug
slug_taken? = slug != data.deployed_app_slug and Livebook.Apps.exists?(slug)

socket =
if slug_taken? do
confirm(socket, on_confirm,
title: "Deploy app",
description:
"An app with this slug already exists, do you want to deploy a new version?",
confirm_text: "Replace"
)
else
on_confirm.(socket)
end

{:noreply, socket}
end

def handle_event("intellisense_request", %{"cell_id" => cell_id} = params, socket) do
request =
case params do
Expand Down
Loading

0 comments on commit ed12966

Please sign in to comment.