Add :debounce to input outputs when missing (#2228)

This commit is contained in:
Jonatan Kłosko 2023-09-26 10:38:15 +07:00 committed by GitHub
parent edc09cd386
commit 05418db0c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 22 deletions

View file

@ -298,28 +298,33 @@ defprotocol Livebook.Runtime do
%{
type: :text,
default: String.t(),
label: String.t()
label: String.t(),
debounce: :blur | non_neg_integer()
}
| %{
type: :textarea,
default: String.t(),
label: String.t(),
debounce: :blur | non_neg_integer(),
monospace: boolean()
}
| %{
type: :password,
default: String.t(),
label: String.t()
label: String.t(),
debounce: :blur | non_neg_integer()
}
| %{
type: :number,
default: number() | nil,
label: String.t()
label: String.t(),
debounce: :blur | non_neg_integer()
}
| %{
type: :url,
default: String.t() | nil,
label: String.t()
label: String.t(),
debounce: :blur | non_neg_integer()
}
| %{
type: :select,
@ -336,6 +341,7 @@ defprotocol Livebook.Runtime do
type: :range,
default: number(),
label: String.t(),
debounce: :blur | non_neg_integer(),
min: number(),
max: number(),
step: number()
@ -364,7 +370,8 @@ defprotocol Livebook.Runtime do
| %{
type: :color,
default: String.t(),
label: String.t()
label: String.t(),
debounce: :blur | non_neg_integer()
}
| %{
type: :image,

View file

@ -2886,39 +2886,70 @@ defmodule Livebook.Session do
end
end
# Maps legacy outputs and adds missing attributes
# Normalizes output to match the most recent specification.
#
# Rewrites legacy output formats and adds defaults for newly introduced
# attributes that are missing.
defp normalize_runtime_output(output)
defp normalize_runtime_output(%{type: :input, attrs: attrs} = output)
when attrs.type in [:text, :textarea, :password, :number, :url, :range, :color] and
not is_map_key(attrs, :debounce) do
put_in(output.attrs[:debounce], :blur)
|> normalize_runtime_output()
end
# Traverse composite outputs
defp normalize_runtime_output(output) when output.type in [:frame, :tabs, :grid] do
outputs = Enum.map(output.outputs, &normalize_runtime_output/1)
%{output | outputs: outputs}
end
defp normalize_runtime_output(%{type: :frame_update} = output) do
{update_type, new_outputs} = output.update
new_outputs = Enum.map(new_outputs, &normalize_runtime_output/1)
%{output | update: {update_type, new_outputs}}
end
defp normalize_runtime_output(output) when is_map(output), do: output
# Rewrite tuples to maps for backward compatibility with Kino <= 0.10.0
defp normalize_runtime_output(:ignored) do
%{type: :ignored}
|> normalize_runtime_output()
end
# Rewrite tuples to maps for backward compatibility with Kino <= 0.10.0
defp normalize_runtime_output({:text, text}) do
%{type: :terminal_text, text: text, chunk: false}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:plain_text, text}) do
%{type: :plain_text, text: text, chunk: false}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:markdown, text}) do
%{type: :markdown, text: text, chunk: false}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:image, content, mime_type}) do
%{type: :image, content: content, mime_type: mime_type}
|> normalize_runtime_output()
end
# Rewrite older output format for backward compatibility with Kino <= 0.5.2
defp normalize_runtime_output({:js, %{ref: ref, pid: pid, assets: assets, export: export}}) do
normalize_runtime_output(
{:js, %{js_view: %{ref: ref, pid: pid, assets: assets}, export: export}}
)
{:js, %{js_view: %{ref: ref, pid: pid, assets: assets}, export: export}}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:js, info}) do
%{type: :js, js_view: info.js_view, export: info.export}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:frame, outputs, %{ref: ref, type: :default} = info}) do
@ -2928,6 +2959,7 @@ defmodule Livebook.Session do
outputs: Enum.map(outputs, &normalize_runtime_output/1),
placeholder: Map.get(info, :placeholder, true)
}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:frame, outputs, %{ref: ref, type: :replace}}) do
@ -2936,6 +2968,7 @@ defmodule Livebook.Session do
ref: ref,
update: {:replace, Enum.map(outputs, &normalize_runtime_output/1)}
}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:frame, outputs, %{ref: ref, type: :append}}) do
@ -2944,10 +2977,12 @@ defmodule Livebook.Session do
ref: ref,
update: {:append, Enum.map(outputs, &normalize_runtime_output/1)}
}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:tabs, outputs, %{labels: labels}}) do
%{type: :tabs, outputs: Enum.map(outputs, &normalize_runtime_output/1), labels: labels}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:grid, outputs, info}) do
@ -2958,6 +2993,7 @@ defmodule Livebook.Session do
gap: Map.get(info, :gap, 8),
boxed: Map.get(info, :boxed, false)
}
|> normalize_runtime_output()
end
defp normalize_runtime_output({:input, attrs}) do
@ -2970,6 +3006,7 @@ defmodule Livebook.Session do
end
Map.merge(fields, %{type: :input, attrs: attrs})
|> normalize_runtime_output()
end
defp normalize_runtime_output({:control, attrs}) do
@ -2992,6 +3029,7 @@ defmodule Livebook.Session do
end
Map.merge(fields, %{type: :control, attrs: attrs})
|> normalize_runtime_output()
end
defp normalize_runtime_output({:error, message, type}) do
@ -3002,9 +3040,11 @@ defmodule Livebook.Session do
end
%{type: :error, message: message, context: context}
|> normalize_runtime_output()
end
defp normalize_runtime_output(other) do
%{type: :unknown, output: other}
|> normalize_runtime_output()
end
end

View file

@ -169,7 +169,7 @@ defmodule LivebookWeb.Output.InputComponent do
class="input-range"
name="html_value"
value={@value}
phx-debounce={@attrs[:debounce] || "blur"}
phx-debounce={@attrs.debounce}
phx-target={@myself}
spellcheck="false"
autocomplete="off"
@ -190,7 +190,7 @@ defmodule LivebookWeb.Output.InputComponent do
class={["input min-h-[38px] max-h-[300px] tiny-scrollbar", @attrs.monospace && "font-mono"]}
name="html_value"
phx-hook="TextareaAutosize"
phx-debounce={@attrs[:debounce] || "blur"}
phx-debounce={@attrs.debounce}
phx-target={@myself}
spellcheck="false"
><%= [?\n, @value] %></textarea>
@ -206,7 +206,7 @@ defmodule LivebookWeb.Output.InputComponent do
class="input w-auto bg-gray-50"
name="html_value"
value={@value}
phx-debounce={@attrs[:debounce] || "blur"}
phx-debounce={@attrs.debounce}
phx-target={@myself}
spellcheck="false"
autocomplete="off"
@ -241,7 +241,7 @@ defmodule LivebookWeb.Output.InputComponent do
class="input w-auto invalid:input--error"
name="html_value"
value={to_string(@value)}
phx-debounce={@attrs[:debounce] || "blur"}
phx-debounce={@attrs.debounce}
phx-target={@myself}
spellcheck="false"
autocomplete="off"

View file

@ -18,7 +18,7 @@ defmodule Livebook.Session.DataTest do
ref: "ref1",
id: "i1",
destination: nil,
attrs: %{type: :text, default: "hey", label: "Text"}
attrs: %{type: :text, default: "hey", label: "Text", debounce: :blur}
}
defp eval_meta(opts \\ []) do
@ -4510,7 +4510,7 @@ defmodule Livebook.Session.DataTest do
ref: "ref1",
id: "i1",
destination: nil,
attrs: %{type: :text, default: "hey", label: "Text"}
attrs: %{type: :text, default: "hey", label: "Text", debounce: :blur}
}
input2 = %{
@ -4518,7 +4518,7 @@ defmodule Livebook.Session.DataTest do
ref: "ref2",
id: "i2",
destination: nil,
attrs: %{type: :text, default: "hey", label: "Text"}
attrs: %{type: :text, default: "hey", label: "Text", debounce: :blur}
}
data =

View file

@ -219,7 +219,7 @@ defmodule Livebook.SessionTest do
ref: "ref",
id: "input1",
destination: :noop,
attrs: %{type: :text, default: "hey", label: "Name"}
attrs: %{type: :text, default: "hey", label: "Name", debounce: :blur}
}
smart_cell = %{
@ -1899,7 +1899,7 @@ defmodule Livebook.SessionTest do
ref: "ref",
id: "input1",
destination: :noop,
attrs: %{type: :text, default: "hey", label: "Name"}
attrs: %{type: :text, default: "hey", label: "Name", debounce: :blur}
}
send(session.pid, {:runtime_evaluation_output, cell_id, legacy_output})

View file

@ -518,7 +518,13 @@ defmodule LivebookWeb.SessionLiveTest do
ref: "ref1",
id: "input1",
destination: test,
attrs: %{type: :textarea, default: "hey", label: "Name", monospace: false}
attrs: %{
type: :textarea,
default: "hey",
label: "Name",
debounce: :blur,
monospace: false
}
}
Session.subscribe(session.id)
@ -552,7 +558,7 @@ defmodule LivebookWeb.SessionLiveTest do
ref: "input_ref1",
id: "input1",
destination: test,
attrs: %{type: :text, default: "initial", label: "Name"}
attrs: %{type: :text, default: "initial", label: "Name", debounce: :blur}
}
],
submit: "Send",
@ -781,7 +787,7 @@ defmodule LivebookWeb.SessionLiveTest do
ref: "ref1",
id: "input1",
destination: test,
attrs: %{type: :number, default: 1, label: "Input inside frame"}
attrs: %{type: :number, default: 1, label: "Input inside frame", debounce: :blur}
}
frame_update = %{