diff --git a/lib/livebook/utils.ex b/lib/livebook/utils.ex
index 59d614c66..24a561f0b 100644
--- a/lib/livebook/utils.ex
+++ b/lib/livebook/utils.ex
@@ -174,7 +174,7 @@ defmodule Livebook.Utils do
if valid_url?(url) do
[]
else
- [{:url, "must be a valid URL"}]
+ [{field, "must be a valid URL"}]
end
end)
end
@@ -257,13 +257,16 @@ defmodule Livebook.Utils do
iex> Livebook.Utils.expand_url("https://example.com/lib/file.ex?token=supersecret", "../root.ex")
"https://example.com/root.ex?token=supersecret"
+ iex> Livebook.Utils.expand_url("https://example.com", "./root.ex")
+ "https://example.com/root.ex"
+
"""
@spec expand_url(String.t(), String.t()) :: String.t()
def expand_url(url, relative_path) do
url
|> URI.parse()
|> Map.update!(:path, fn path ->
- Livebook.FileSystem.Utils.resolve_unix_like_path(path, relative_path)
+ Livebook.FileSystem.Utils.resolve_unix_like_path(path || "/", relative_path)
end)
|> URI.to_string()
end
diff --git a/lib/livebook_web/live/open_live/source_component.ex b/lib/livebook_web/live/open_live/source_component.ex
index f06bb9d86..232379284 100644
--- a/lib/livebook_web/live/open_live/source_component.ex
+++ b/lib/livebook_web/live/open_live/source_component.ex
@@ -1,9 +1,19 @@
defmodule LivebookWeb.OpenLive.SourceComponent do
use LivebookWeb, :live_component
+ import Ecto.Changeset
+
@impl true
def mount(socket) do
- {:ok, assign(socket, source: "")}
+ {:ok, assign(socket, changeset: changeset())}
+ end
+
+ defp changeset(attrs \\ %{}) do
+ data = %{source: nil}
+ types = %{source: :string}
+
+ cast({data, types}, attrs, [:source])
+ |> validate_required([:source])
end
@impl true
@@ -16,7 +26,7 @@ defmodule LivebookWeb.OpenLive.SourceComponent do
<.form
:let={f}
- for={%{"source" => @source}}
+ for={@changeset}
as={:data}
id="import-source"
phx-submit="import"
@@ -25,7 +35,6 @@ defmodule LivebookWeb.OpenLive.SourceComponent do
autocomplete="off"
>
<.textarea_field
- type="textarea"
field={f[:source]}
label="Notebook source"
resizable={false}
@@ -34,7 +43,7 @@ defmodule LivebookWeb.OpenLive.SourceComponent do
spellcheck="false"
rows="5"
/>
-