mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-09 04:57:18 +08:00
Minimize lifespan of param-driven assigns (#2509)
This commit is contained in:
parent
0d6a50552e
commit
1a8d46a89a
4 changed files with 89 additions and 96 deletions
|
@ -83,8 +83,7 @@ defmodule LivebookWeb.SessionLive do
|
||||||
data_view: data_to_view(data),
|
data_view: data_to_view(data),
|
||||||
autofocus_cell_id: autofocus_cell_id(data.notebook),
|
autofocus_cell_id: autofocus_cell_id(data.notebook),
|
||||||
page_title: get_page_title(data.notebook.name),
|
page_title: get_page_title(data.notebook.name),
|
||||||
select_secret_ref: nil,
|
action_assigns: %{},
|
||||||
select_secret_options: nil,
|
|
||||||
allowed_uri_schemes: Livebook.Config.allowed_uri_schemes(),
|
allowed_uri_schemes: Livebook.Config.allowed_uri_schemes(),
|
||||||
starred_files: Livebook.NotebookManager.starred_notebooks() |> starred_files()
|
starred_files: Livebook.NotebookManager.starred_notebooks() |> starred_files()
|
||||||
)
|
)
|
||||||
|
@ -127,35 +126,62 @@ defmodule LivebookWeb.SessionLive do
|
||||||
defdelegate render(assigns), to: LivebookWeb.SessionLive.Render
|
defdelegate render(assigns), to: LivebookWeb.SessionLive.Render
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_params(%{"cell_id" => cell_id}, _url, socket)
|
def handle_params(params, url, socket) do
|
||||||
when socket.assigns.live_action == :cell_settings do
|
{socket, action_assigns} = handle_params(socket.assigns.live_action, params, url, socket)
|
||||||
|
socket = assign(socket, :action_assigns, action_assigns)
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_params(:cell_settings, %{"cell_id" => cell_id}, _url, socket) do
|
||||||
{:ok, cell, _} = Notebook.fetch_cell_and_section(socket.private.data.notebook, cell_id)
|
{:ok, cell, _} = Notebook.fetch_cell_and_section(socket.private.data.notebook, cell_id)
|
||||||
{:noreply, assign(socket, cell: cell)}
|
{socket, %{cell: cell}}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_params(%{}, _url, socket)
|
defp handle_params(:insert_image, %{}, _url, socket) do
|
||||||
when socket.assigns.live_action == :insert_image and
|
case pop_in(socket.assigns[:insert_image_metadata]) do
|
||||||
not is_map_key(socket.assigns, :insert_image_metadata) do
|
{nil, socket} -> {redirect_to_self(socket), %{}}
|
||||||
{:noreply, redirect_to_self(socket)}
|
{metadata, socket} -> {socket, %{insert_image_metadata: metadata}}
|
||||||
end
|
|
||||||
|
|
||||||
def handle_params(%{}, _url, socket)
|
|
||||||
when socket.assigns.live_action == :insert_file and
|
|
||||||
not is_map_key(socket.assigns, :insert_file_metadata) do
|
|
||||||
{:noreply, redirect_to_self(socket)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_params(%{"name" => name}, _url, socket)
|
|
||||||
when socket.assigns.live_action == :rename_file_entry do
|
|
||||||
if file_entry = find_file_entry(socket, name) do
|
|
||||||
{:noreply, assign(socket, renaming_file_entry: file_entry)}
|
|
||||||
else
|
|
||||||
{:noreply, redirect_to_self(socket)}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_params(%{"path_parts" => path_parts}, requested_url, socket)
|
defp handle_params(:insert_file, %{}, _url, socket) do
|
||||||
when socket.assigns.live_action == :catch_all do
|
case pop_in(socket.assigns[:insert_file_metadata]) do
|
||||||
|
{nil, socket} -> {redirect_to_self(socket), %{}}
|
||||||
|
{metadata, socket} -> {socket, %{insert_file_metadata: metadata}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_params(:rename_file_entry, %{"name" => name}, _url, socket) do
|
||||||
|
if file_entry = find_file_entry(socket, name) do
|
||||||
|
{socket, %{renaming_file_entry: file_entry}}
|
||||||
|
else
|
||||||
|
{redirect_to_self(socket), %{}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_params(:export, %{"tab" => tab}, _url, socket) do
|
||||||
|
any_stale_cell? = any_stale_cell?(socket.private.data)
|
||||||
|
{socket, %{tab: tab, any_stale_cell?: any_stale_cell?}}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_params(:add_file_entry, %{"tab" => tab}, _url, socket) do
|
||||||
|
{file_drop_metadata, socket} = pop_in(socket.assigns[:file_drop_metadata])
|
||||||
|
{socket, %{tab: tab, file_drop_metadata: file_drop_metadata}}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_params(:secrets, params, _url, socket) do
|
||||||
|
{select_secret_metadata, socket} = pop_in(socket.assigns[:select_secret_metadata])
|
||||||
|
|
||||||
|
{socket,
|
||||||
|
%{select_secret_metadata: select_secret_metadata, prefill_secret_name: params["secret_name"]}}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_params(live_action, params, _url, socket)
|
||||||
|
when live_action in [:app_settings, :file_settings] do
|
||||||
|
{socket, %{context: params["context"]}}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_params(:catch_all, %{"path_parts" => path_parts}, requested_url, socket) do
|
||||||
path_parts =
|
path_parts =
|
||||||
Enum.map(path_parts, fn
|
Enum.map(path_parts, fn
|
||||||
"__parent__" -> ".."
|
"__parent__" -> ".."
|
||||||
|
@ -163,46 +189,12 @@ defmodule LivebookWeb.SessionLive do
|
||||||
end)
|
end)
|
||||||
|
|
||||||
path = Path.join(path_parts)
|
path = Path.join(path_parts)
|
||||||
{:noreply, handle_relative_path(socket, path, requested_url)}
|
socket = handle_relative_path(socket, path, requested_url)
|
||||||
|
{socket, %{}}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_params(%{"tab" => tab}, _url, socket) when socket.assigns.live_action == :export do
|
defp handle_params(_live_action, _params, _url, socket) do
|
||||||
any_stale_cell? = any_stale_cell?(socket.private.data)
|
{socket, %{}}
|
||||||
{:noreply, assign(socket, tab: tab, any_stale_cell?: any_stale_cell?)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_params(%{"tab" => tab} = params, _url, socket)
|
|
||||||
when socket.assigns.live_action == :add_file_entry do
|
|
||||||
file_drop_metadata =
|
|
||||||
if(params["file_drop"] == "true", do: socket.assigns[:file_drop_metadata])
|
|
||||||
|
|
||||||
{:noreply, assign(socket, tab: tab, file_drop_metadata: file_drop_metadata)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_params(params, _url, socket)
|
|
||||||
when socket.assigns.live_action == :secrets do
|
|
||||||
socket =
|
|
||||||
if params["preselect_name"] do
|
|
||||||
assign(socket, prefill_secret_name: params["preselect_name"])
|
|
||||||
else
|
|
||||||
# Erase any previously stored reference
|
|
||||||
assign(socket,
|
|
||||||
prefill_secret_name: params["secret_name"],
|
|
||||||
select_secret_ref: nil,
|
|
||||||
select_secret_options: nil
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
{:noreply, socket}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_params(params, _url, socket)
|
|
||||||
when socket.assigns.live_action in [:app_settings, :file_settings] do
|
|
||||||
{:noreply, assign(socket, route_params: Map.take(params, ["context"]))}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_params(_params, _url, socket) do
|
|
||||||
{:noreply, socket}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -695,13 +687,15 @@ defmodule LivebookWeb.SessionLive do
|
||||||
) do
|
) do
|
||||||
socket =
|
socket =
|
||||||
assign(socket,
|
assign(socket,
|
||||||
select_secret_ref: select_secret_ref,
|
select_secret_metadata: %{
|
||||||
select_secret_options: select_secret_options
|
ref: select_secret_ref,
|
||||||
|
options: select_secret_options
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
{:noreply,
|
{:noreply,
|
||||||
push_patch(socket,
|
push_patch(socket,
|
||||||
to: ~p"/sessions/#{socket.assigns.session.id}/secrets?preselect_name=#{preselect_name}"
|
to: ~p"/sessions/#{socket.assigns.session.id}/secrets?secret_name=#{preselect_name}"
|
||||||
)}
|
)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -792,7 +786,7 @@ defmodule LivebookWeb.SessionLive do
|
||||||
|
|
||||||
def handle_event("insert_file_action", %{"idx" => idx}, socket) do
|
def handle_event("insert_file_action", %{"idx" => idx}, socket) do
|
||||||
%{section_id: section_id, cell_id: cell_id, file_entry: file_entry, handlers: handlers} =
|
%{section_id: section_id, cell_id: cell_id, file_entry: file_entry, handlers: handlers} =
|
||||||
socket.assigns.insert_file_metadata
|
socket.assigns.action_assigns.insert_file_metadata
|
||||||
|
|
||||||
handler = Enum.fetch!(handlers, idx)
|
handler = Enum.fetch!(handlers, idx)
|
||||||
source = String.replace(handler.definition.source, "{{NAME}}", file_entry.name)
|
source = String.replace(handler.definition.source, "{{NAME}}", file_entry.name)
|
||||||
|
@ -834,9 +828,7 @@ defmodule LivebookWeb.SessionLive do
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
socket
|
||||||
|> assign(file_drop_metadata: %{section_id: section_id, cell_id: cell_id})
|
|> assign(file_drop_metadata: %{section_id: section_id, cell_id: cell_id})
|
||||||
|> push_patch(
|
|> push_patch(to: ~p"/sessions/#{socket.assigns.session.id}/add-file/upload")
|
||||||
to: ~p"/sessions/#{socket.assigns.session.id}/add-file/upload?file_drop=true"
|
|
||||||
)
|
|
||||||
|> push_event("finish_file_drop", %{})}
|
|> push_event("finish_file_drop", %{})}
|
||||||
else
|
else
|
||||||
reason = "To see the available options, you need a connected runtime."
|
reason = "To see the available options, you need a connected runtime."
|
||||||
|
@ -847,8 +839,7 @@ defmodule LivebookWeb.SessionLive do
|
||||||
def handle_event("handle_file_drop", %{}, socket) do
|
def handle_event("handle_file_drop", %{}, socket) do
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
socket
|
||||||
|> assign(file_drop_metadata: nil)
|
|> push_patch(to: ~p"/sessions/#{socket.assigns.session.id}/add-file/upload")
|
||||||
|> push_patch(to: ~p"/sessions/#{socket.assigns.session.id}/add-file/upload?file_drop=true")
|
|
||||||
|> push_event("finish_file_drop", %{})}
|
|> push_event("finish_file_drop", %{})}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1004,7 +995,7 @@ defmodule LivebookWeb.SessionLive do
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_info({:file_entry_uploaded, file_entry}, socket) do
|
def handle_info({:file_entry_uploaded, file_entry}, socket) do
|
||||||
case socket.assigns.file_drop_metadata do
|
case socket.assigns.action_assigns[:file_drop_metadata] do
|
||||||
%{section_id: section_id, cell_id: cell_id} ->
|
%{section_id: section_id, cell_id: cell_id} ->
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
socket
|
||||||
|
@ -1019,7 +1010,7 @@ defmodule LivebookWeb.SessionLive do
|
||||||
|> push_patch(to: ~p"/sessions/#{socket.assigns.session.id}/insert-file")}
|
|> push_patch(to: ~p"/sessions/#{socket.assigns.session.id}/insert-file")}
|
||||||
|
|
||||||
nil ->
|
nil ->
|
||||||
{:noreply, socket}
|
{:noreply, push_patch(socket, to: ~p"/sessions/#{socket.assigns.session.id}")}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ defmodule LivebookWeb.SessionLive.AddFileEntryUploadComponent do
|
||||||
file_entry = %{name: data.name, type: :attachment}
|
file_entry = %{name: data.name, type: :attachment}
|
||||||
Livebook.Session.add_file_entries(socket.assigns.session.pid, [file_entry])
|
Livebook.Session.add_file_entries(socket.assigns.session.pid, [file_entry])
|
||||||
send(self(), {:file_entry_uploaded, file_entry})
|
send(self(), {:file_entry_uploaded, file_entry})
|
||||||
{:noreply, push_patch(socket, to: ~p"/sessions/#{socket.assigns.session.id}")}
|
{:noreply, socket}
|
||||||
|
|
||||||
{:error, changeset} ->
|
{:error, changeset} ->
|
||||||
{:noreply, assign(socket, changeset: changeset)}
|
{:noreply, assign(socket, changeset: changeset)}
|
||||||
|
|
|
@ -72,7 +72,7 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
session={@session}
|
session={@session}
|
||||||
file={@data_view.file}
|
file={@data_view.file}
|
||||||
hub={@data_view.hub}
|
hub={@data_view.hub}
|
||||||
context={@route_params["context"]}
|
context={@action_assigns.context}
|
||||||
persist_outputs={@data_view.persist_outputs}
|
persist_outputs={@data_view.persist_outputs}
|
||||||
autosave_interval_s={@data_view.autosave_interval_s}
|
autosave_interval_s={@data_view.autosave_interval_s}
|
||||||
/>
|
/>
|
||||||
|
@ -90,7 +90,7 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
id="app-settings"
|
id="app-settings"
|
||||||
session={@session}
|
session={@session}
|
||||||
settings={@data_view.app_settings}
|
settings={@data_view.app_settings}
|
||||||
context={@route_params["context"]}
|
context={@action_assigns.context}
|
||||||
deployed_app_slug={@data_view.deployed_app_slug}
|
deployed_app_slug={@data_view.deployed_app_slug}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
@ -127,7 +127,7 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
session={@session}
|
session={@session}
|
||||||
hub={@data_view.hub}
|
hub={@data_view.hub}
|
||||||
file_entries={@data_view.file_entries}
|
file_entries={@data_view.file_entries}
|
||||||
tab={@tab}
|
tab={@action_assigns.tab}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
module={LivebookWeb.SessionLive.RenameFileEntryComponent}
|
module={LivebookWeb.SessionLive.RenameFileEntryComponent}
|
||||||
id="rename-file-entry"
|
id="rename-file-entry"
|
||||||
session={@session}
|
session={@session}
|
||||||
file_entry={@renaming_file_entry}
|
file_entry={@action_assigns.renaming_file_entry}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
|
||||||
|
@ -168,11 +168,11 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
patch={@self_path}
|
patch={@self_path}
|
||||||
>
|
>
|
||||||
<.live_component
|
<.live_component
|
||||||
module={settings_component_for(@cell)}
|
module={settings_component_for(@action_assigns.cell)}
|
||||||
id="cell-settings"
|
id="cell-settings"
|
||||||
session={@session}
|
session={@session}
|
||||||
return_to={@self_path}
|
return_to={@self_path}
|
||||||
cell={@cell}
|
cell={@action_assigns.cell}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
id="insert-image"
|
id="insert-image"
|
||||||
session={@session}
|
session={@session}
|
||||||
return_to={@self_path}
|
return_to={@self_path}
|
||||||
insert_image_metadata={@insert_image_metadata}
|
insert_image_metadata={@action_assigns.insert_image_metadata}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
id="insert-file"
|
id="insert-file"
|
||||||
session={@session}
|
session={@session}
|
||||||
return_to={@self_path}
|
return_to={@self_path}
|
||||||
insert_file_metadata={@insert_file_metadata}
|
insert_file_metadata={@action_assigns.insert_file_metadata}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
|
||||||
|
@ -223,8 +223,8 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
module={LivebookWeb.SessionLive.ExportComponent}
|
module={LivebookWeb.SessionLive.ExportComponent}
|
||||||
id="export"
|
id="export"
|
||||||
session={@session}
|
session={@session}
|
||||||
tab={@tab}
|
tab={@action_assigns.tab}
|
||||||
any_stale_cell?={@any_stale_cell?}
|
any_stale_cell?={@action_assigns.any_stale_cell?}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
:if={@live_action == :secrets}
|
:if={@live_action == :secrets}
|
||||||
id="secrets-modal"
|
id="secrets-modal"
|
||||||
show
|
show
|
||||||
width={if(@select_secret_ref, do: :large, else: :medium)}
|
width={if(@action_assigns.select_secret_metadata, do: :large, else: :medium)}
|
||||||
patch={@self_path}
|
patch={@self_path}
|
||||||
>
|
>
|
||||||
<.live_component
|
<.live_component
|
||||||
|
@ -258,9 +258,8 @@ defmodule LivebookWeb.SessionLive.Render do
|
||||||
secrets={@data_view.secrets}
|
secrets={@data_view.secrets}
|
||||||
hub_secrets={@data_view.hub_secrets}
|
hub_secrets={@data_view.hub_secrets}
|
||||||
hub={@data_view.hub}
|
hub={@data_view.hub}
|
||||||
prefill_secret_name={@prefill_secret_name}
|
select_secret_metadata={@action_assigns.select_secret_metadata}
|
||||||
select_secret_ref={@select_secret_ref}
|
prefill_secret_name={@action_assigns.prefill_secret_name}
|
||||||
select_secret_options={@select_secret_options}
|
|
||||||
return_to={@self_path}
|
return_to={@self_path}
|
||||||
/>
|
/>
|
||||||
</.modal>
|
</.modal>
|
||||||
|
|
|
@ -15,7 +15,7 @@ defmodule LivebookWeb.SessionLive.SecretsComponent do
|
||||||
def update(assigns, socket) do
|
def update(assigns, socket) do
|
||||||
socket = assign(socket, assigns)
|
socket = assign(socket, assigns)
|
||||||
|
|
||||||
secret_name = socket.assigns[:prefill_secret_name]
|
secret_name = socket.assigns.prefill_secret_name
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|
@ -48,7 +48,7 @@ defmodule LivebookWeb.SessionLive.SecretsComponent do
|
||||||
hub={@hub}
|
hub={@hub}
|
||||||
/>
|
/>
|
||||||
<div class="flex flex-columns gap-4">
|
<div class="flex flex-columns gap-4">
|
||||||
<div :if={@select_secret_ref} class="basis-1/2 grow-0 pr-4 border-r">
|
<div :if={@select_secret_metadata} class="basis-1/2 grow-0 pr-4 border-r">
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
<p class="text-gray-800">
|
<p class="text-gray-800">
|
||||||
Choose a secret
|
Choose a secret
|
||||||
|
@ -98,7 +98,7 @@ defmodule LivebookWeb.SessionLive.SecretsComponent do
|
||||||
class="basis-1/2 grow"
|
class="basis-1/2 grow"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
<p :if={@select_secret_ref} class="text-gray-700">
|
<p :if={@select_secret_metadata} class="text-gray-700">
|
||||||
Add new secret
|
Add new secret
|
||||||
</p>
|
</p>
|
||||||
<.text_field
|
<.text_field
|
||||||
|
@ -258,14 +258,17 @@ defmodule LivebookWeb.SessionLive.SecretsComponent do
|
||||||
|> push_secret_selected(secret_name)}
|
|> push_secret_selected(secret_name)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp push_secret_selected(%{assigns: %{select_secret_ref: nil}} = socket, _), do: socket
|
defp push_secret_selected(%{assigns: %{select_secret_metadata: nil}} = socket, _), do: socket
|
||||||
|
|
||||||
defp push_secret_selected(%{assigns: %{select_secret_ref: ref}} = socket, secret_name) do
|
defp push_secret_selected(
|
||||||
|
%{assigns: %{select_secret_metadata: %{ref: ref}}} = socket,
|
||||||
|
secret_name
|
||||||
|
) do
|
||||||
push_event(socket, "secret_selected", %{select_secret_ref: ref, secret_name: secret_name})
|
push_event(socket, "secret_selected", %{select_secret_ref: ref, secret_name: secret_name})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp title(%{assigns: %{select_secret_ref: nil}}), do: "Add secret"
|
defp title(%{assigns: %{select_secret_metadata: nil}}), do: "Add secret"
|
||||||
defp title(%{assigns: %{select_secret_options: %{"title" => title}}}), do: title
|
defp title(%{assigns: %{select_secret_metadata: %{options: %{"title" => title}}}}), do: title
|
||||||
defp title(_), do: "Select secret"
|
defp title(_), do: "Select secret"
|
||||||
|
|
||||||
defp set_secret(socket, %Secret{hub_id: nil} = secret) do
|
defp set_secret(socket, %Secret{hub_id: nil} = secret) do
|
||||||
|
|
Loading…
Add table
Reference in a new issue