Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Form to "+ Block" #1750

Merged
merged 6 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion assets/js/hooks/confirm_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,13 @@ const ConfirmModal = {
}
};

// Events dispatched with JS.dispatch
window.addEventListener("lb:confirm_request", this.handleConfirmRequest);
// Events dispatched with push_event
window.addEventListener(
"phx:lb:confirm_request",
this.handleConfirmRequest
);

this.el.addEventListener("lb:confirm", (event) => {
const { opt_out_id } = confirmEvent.detail;
Expand All @@ -71,12 +77,21 @@ const ConfirmModal = {
store(OPT_OUT_IDS_KEY, optedOutIds);
}

liveSocket.execJS(confirmEvent.target, confirmEvent.detail.on_confirm);
// Events dispatched with push_event have window as target,
// in which case we pass body, which is an actual element
const target =
confirmEvent.target === window ? document.body : confirmEvent.target;

liveSocket.execJS(target, confirmEvent.detail.on_confirm);
});
},

destroyed() {
window.removeEventListener("lb:confirm_request", this.handleConfirmRequest);
window.removeEventListener(
"phx:lb:confirm_request",
this.handleConfirmRequest
);
},
};

Expand Down
35 changes: 28 additions & 7 deletions lib/livebook/runtime.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,17 +209,13 @@ defprotocol Livebook.Runtime do
* `{:runtime_smart_cell_definitions, list(smart_cell_definition())}`

Additionally, the runtime may report extra definitions that require
installing external packages, as described by `:requirement`. Also
see `add_dependencies/3`.
installing external packages, as described by `:requirement_presets`.
Also see `add_dependencies/3`.
"""
@type smart_cell_definition :: %{
kind: String.t(),
name: String.t(),
requirement: nil | smart_cell_requirement()
}

@type smart_cell_requirement :: %{
variants:
requirement_presets:
list(%{
name: String.t(),
packages: list(%{name: String.t(), dependency: dependency()})
Expand All @@ -238,6 +234,19 @@ defprotocol Livebook.Runtime do
dependency: dependency()
}

@typedoc """
An information about a predefined code block.
"""
@type code_block_definition :: %{
name: String.t(),
variants:
list(%{
name: String.t(),
source: String.t(),
packages: list(%{name: String.t(), dependency: dependency()})
})
}

@typedoc """
A JavaScript view definition.

Expand Down Expand Up @@ -535,6 +544,18 @@ defprotocol Livebook.Runtime do
{:ok, String.t()} | {:error, String.t()}
def add_dependencies(runtime, code, dependencies)

@doc """
Checks if the given dependencies are installed within the runtime.
"""
@spec has_dependencies?(t(), list(dependency())) :: boolean()
def has_dependencies?(runtime, dependencies)

@doc """
Returns a list of predefined code blocks.
"""
@spec code_block_definitions(t()) :: list(code_block_definition())
def code_block_definitions(runtime)

@doc """
Looks up packages matching the given search.

Expand Down
8 changes: 8 additions & 0 deletions lib/livebook/runtime/attached.ex
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.Attached do
raise "not supported"
end

def has_dependencies?(runtime, dependencies) do
RuntimeServer.has_dependencies?(runtime.server_pid, dependencies)
end

def code_block_definitions(_runtime) do
Livebook.Runtime.Definitions.code_block_definitions()
end

def search_packages(_runtime, _send_to, _search) do
raise "not supported"
end
Expand Down
192 changes: 192 additions & 0 deletions lib/livebook/runtime/definitions.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
defmodule Livebook.Runtime.Definitions do
@moduledoc false

kino = %{
name: "kino",
dependency: %{dep: {:kino, "~> 0.9.3"}, config: []}
}

kino_vega_lite = %{
name: "kino_vega_lite",
dependency: %{dep: {:kino_vega_lite, "~> 0.1.7"}, config: []}
}

kino_db = %{
name: "kino_db",
dependency: %{dep: {:kino_db, "~> 0.2.1"}, config: []}
}

kino_maplibre = %{
name: "kino_maplibre",
dependency: %{dep: {:kino_maplibre, "~> 0.1.7"}, config: []}
}

kino_slack = %{
name: "kino_slack",
dependency: %{dep: {:kino_slack, "~> 0.1.1"}, config: []}
}

kino_bumblebee = %{
name: "kino_bumblebee",
dependency: %{dep: {:kino_bumblebee, "~> 0.3.0"}, config: []}
}

exla = %{
name: "exla",
dependency: %{dep: {:exla, "~> 0.5.1"}, config: [nx: [default_backend: EXLA.Backend]]}
}

torchx = %{
name: "torchx",
dependency: %{dep: {:torchx, "~> 0.5.1"}, config: [nx: [default_backend: Torchx.Backend]]}
}

kino_explorer = %{
name: "kino_explorer",
dependency: %{dep: {:kino_explorer, "~> 0.1.4"}, config: []}
}

windows? = match?({:win32, _}, :os.type())
nx_backend_package = if(windows?, do: torchx, else: exla)

@smart_cell_definitions [
%{
kind: "Elixir.KinoDB.ConnectionCell",
name: "Database connection",
requirement_presets: [
%{
name: "Amazon Athena",
packages: [
kino_db,
%{
name: "req_athena",
dependency: %{dep: {:req_athena, "~> 0.1.3"}, config: []}
}
]
},
%{
name: "Google BigQuery",
packages: [
kino_db,
%{
name: "req_bigquery",
dependency: %{dep: {:req_bigquery, "~> 0.1.1"}, config: []}
}
]
},
%{
name: "MySQL",
packages: [
kino_db,
%{name: "myxql", dependency: %{dep: {:myxql, "~> 0.6.2"}, config: []}}
]
},
%{
name: "PostgreSQL",
packages: [
kino_db,
%{name: "postgrex", dependency: %{dep: {:postgrex, "~> 0.16.3"}, config: []}}
]
},
%{
name: "SQLite",
packages: [
kino_db,
%{name: "exqlite", dependency: %{dep: {:exqlite, "~> 0.11.0"}, config: []}}
]
}
]
},
%{
kind: "Elixir.KinoDB.SQLCell",
name: "SQL query",
requirement_presets: [
%{
name: "Default",
packages: [kino_db]
}
]
},
%{
kind: "Elixir.KinoVegaLite.ChartCell",
name: "Chart",
requirement_presets: [
%{
name: "Default",
packages: [kino_vega_lite]
}
]
},
%{
kind: "Elixir.KinoMapLibre.MapCell",
name: "Map",
requirement_presets: [
%{
name: "Default",
packages: [kino_maplibre]
}
]
},
%{
kind: "Elixir.KinoSlack.MessageCell",
name: "Slack message",
requirement_presets: [
%{
name: "Default",
packages: [kino_slack]
}
]
},
%{
kind: "Elixir.KinoBumblebee.TaskCell",
name: "Neural Network task",
requirement_presets: [
%{
name: "Default",
packages: [kino_bumblebee, nx_backend_package]
}
]
},
%{
kind: "Elixir.KinoExplorer.DataTransformCell",
name: "Data transform",
requirement_presets: [
%{
name: "Default",
packages: [kino_explorer]
}
]
}
]

@code_block_definitions [
%{
name: "Form",
variants: [
%{
name: "Default",
source: """
form =
Kino.Control.form(
[
name: Kino.Input.text("Name")
],
submit: "Submit"
)

Kino.listen(form, fn event ->
IO.inspect(event)
end)

form\
Comment on lines +169 to +181
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josevalim I updated the snippet to remove the explicit render, and this way we return just the form rather than :ok, but feel free to change :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

""",
packages: [kino]
}
]
}
]

def smart_cell_definitions(), do: @smart_cell_definitions

def code_block_definitions(), do: @code_block_definitions
end
Loading