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

Conversation

ByeongUkChoi
Copy link
Contributor

via. #1743

I've tried to write it roughly.
I would like to get some advice on putting input_cells_definitions in Runtime.

@github-actions
Copy link

github-actions bot commented Mar 5, 2023

Uffizzi Preview deployment-18167 was deleted.

@ByeongUkChoi ByeongUkChoi marked this pull request as draft March 5, 2023 15:25
@josevalim
Copy link
Contributor

Hi @ByeongUkChoi! I realized I made a mistake. Actually, we don't want to push people towards using these inputs because they won't work with apps. Instead, we should push them towards forms, so I think we can do some small changes:

  1. When you click "+ Block", there will be a new option called "Form". This option will be between Diagram and Image
  2. Once you click it, it will prompt to install Kino if not yet installed
  3. Then you will generate this code
form =
  Kino.Control.form(
    [
      name: Kino.Input.text("Name"),
    ],
    submit: "Submit"
  )

form
|> Kino.render()
|> Kino.Control.stream()
|> Kino.listen(fn event ->
  IO.inspect(event)
end)

Apologies for the back and forth.

What do you think @jonatanklosko? Also, should we make Kino.Input and Kino.Control enumerables by default, so we can skip the conversion in Kino.Control.stream? Or should we make it so Kino.listen also handles these two and convert them automatically? Maybe we should make it so the API in Control.stream and Control.tagged_stream are part of listen?

Kino.listen([input1, input2, input3], fn ... -> ... end)
Kino.listen([tag1: input1, tag2: input2, tag: input3], fn ... -> ... end)

The only issue is that there is some ambiguity if you want to listen to an actual list, but then I don't see the point and we can raise if it is not a list of event sources.

@josevalim
Copy link
Contributor

PR for simplifying listen here: https://github.com/livebook-dev/kino/pull/261/files

@jonatanklosko
Copy link
Member

Actually, we don't want to push people towards using these inputs because they won't work with apps. Instead, we should push them towards form

It very much depends on the use case, we shouldn't be pushing towards either because it's all up to what they want to do 🤔

Or should we make it so Kino.listen also handles these two and convert them automatically?

There's also Kino.animate akin to listen, I like how we unified it all so that both just accept an enumerable. It feels weird if they accept all of control, list of controls, keyword list of controls, or enumerable.

@josevalim
Copy link
Contributor

@jonatanklosko at the moment, forms have more use in apps, so let’s push towards that first. We can add inputs once runbooks are a thing.

let’s discuss the control/input stuff in the kino PR? :)

@ByeongUkChoi ByeongUkChoi marked this pull request as ready for review March 7, 2023 16:35
@josevalim
Copy link
Contributor

@ByeongUkChoi this looks great. Just one note: you are asking to install the Kino package, even when it is already installed. Can we address this somehow? Thank you! ❤️

@ByeongUkChoi
Copy link
Contributor Author

@ByeongUkChoi this looks great. Just one note: you are asking to install the Kino package, even when it is already installed. Can we address this somehow? Thank you! ❤️

@josevalim @jonatanklosko
Can you give me an idea on this part?

@jonatanklosko
Copy link
Member

Ah this is tricky, for smart cells, once packages are installed the runtime reports installed smart cells and indicates they have no "requirements" (which overrides the initial definition with "requirements"). I think we will need to pass input/snippet definitions to the runtime and let it filter out the requirements that are satisfied.

If you want to take a stab at this, you look at how we configure smart cell definitions:

runtime_server_opts: [extra_smart_cell_definitions: @extra_smart_cell_definitions]

If you prefer me to have a look, I can do that later, it's fine either way!

@ByeongUkChoi
Copy link
Contributor Author

@jonatanklosko
Thank you for advise.
I have some idea

1. form definition put in @extra_smart_cell_definitions (Livebook.Runtime.ElixirStandalone). like this:

  @extra_smart_cell_definitions [
    ...
    %{
      kind: "Elixir.Kino.Form",
      name: "Form",
      requirement: %{
        variants: [
          %{name: "Default", packages: [kino]}
        ]
      }
    }
  ]

but this case. not found definitions

# Livebook.Runtime.ErlDist.RuntimeServer.report_smart_cell_definitions/1
smart_cell_definitions = get_smart_cell_definitions(state.smart_cell_definitions_module)
# []

So I can't replace to requirement: nil

2. Save the form_cell_definition in a new field.

But I don't know where to start creating this field.

@jonatanklosko
Copy link
Member

@ByeongUkChoi the flow is going to be similar to smart cells, but it needs to be separate, like @extra_input_definitions. Then after evaluation we need to look at the requirements and filter out those that are satisfied.

@ByeongUkChoi
Copy link
Contributor Author

@jonatanklosko
However, upon initial initialization, the value of @data_view.smart_cell_definitions is []. Then, by clicking the +Smart button and pressing the Setup runtime button in the Setup runtime modal, the value of smart_cell_definitions is created. What about input_definitions? Shouldn't we be able to press Form without Setup runtime?

@jonatanklosko
Copy link
Member

@ByeongUkChoi I think need the runtime (and hence the "Setup runtime" modal), otherwise we don't know if the dependency is installed.

@ByeongUkChoi
Copy link
Contributor Author

@jonatanklosko So when open "Setup runtime" modal? For smart cells, when I press the "+Smart" button, a modal pops up.
Should the "Setup runtime" modal appear when I press the "Form" button inside the "+Block"?

@jonatanklosko
Copy link
Member

We should have "+ Input", and if the runtime is not started then clicking on it will show "Setup runtime", otherwise it will have a sub-menu with the available inputs, just as we have for smart cells :)

@josevalim
Copy link
Contributor

josevalim commented May 8, 2023

Sorry, there is some confusion. We gave up on + Inputs for now. Instead we will have a "Form" item inside the + Block one.

@josevalim josevalim changed the title add "+ Inputs" button Add Form to "+ Block" May 8, 2023
@jonatanklosko
Copy link
Member

@josevalim but we want to list multiple variants, or just the text one?

@josevalim
Copy link
Contributor

@jonatanklosko just the text one for now, I think we only need something to get started and people will build the rest.

@jonatanklosko
Copy link
Member

jonatanklosko commented May 8, 2023

Ah I see. In that case I think we can do either:

  1. Let the runtime report snippets and add them to the blocks (only appear once the runtime is started).
  2. Have a snippets button under blocks, so it's + Block > Snippets. The first click shows "Setup runtime", and once started it becomes a sublist with reported snippets (in this case just "Form").

@josevalim
Copy link
Contributor

@jonatanklosko why can't we always show the "Form" button? Is it because we cannot always add Kino? Maybe we can just ask the runtime if it can install dependencies instead? That should be enough, no?

@jonatanklosko
Copy link
Member

@josevalim if we want to show the modal saying "Requires :kino, do you want to add it and restart?" (only if kino is missing), then we need to know whether kino is added.

Alternatively we could analyze the setup cell to check if the dependency is there. It's a bit less reliable, because if there is :kino_vega_lite then kino is already there (though arguably listing kino explicitly is a good thing).

Sidenote: in the future we could add a kino API for registering custom snippets, just something to keep in mind.

@jonatanklosko
Copy link
Member

@ByeongUkChoi sorry for the back and forth, I discussed with Jose offline and we figured the desired behaviour. There are some tiny complexities and I think it's easier for me to finish, thanks for the prototype! :)

@ByeongUkChoi
Copy link
Contributor Author

@jonatanklosko Great! So How can I do?

@jonatanklosko
Copy link
Member

@ByeongUkChoi it's all good, what I meant is that I will finish the implementation :D

Comment on lines +169 to +181
form =
Kino.Control.form(
[
name: Kino.Input.text("Name")
],
submit: "Submit"
)

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

form\
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!

Comment on lines -155 to -157
with_confirm(
JS.push("add_smart_cell_dependencies",
value: %{kind: definition.kind, variant_idx: variant_idx}
Copy link
Member

@jonatanklosko jonatanklosko May 9, 2023

Choose a reason for hiding this comment

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

I moved this confirm to the server too, this way they are more aligned. It also reduces the rendered payload at a cost of an additional roundtrip when they hit insert and we need to add deps (which sounds fair).

@jonatanklosko jonatanklosko merged commit 6dd19a8 into livebook-dev:main May 9, 2023
@ByeongUkChoi ByeongUkChoi deleted the feature/ISSUE-1743 branch May 9, 2023 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants