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

feat: deephaven.ui plugin prototype initial checkin #47

Merged
merged 53 commits into from
Oct 5, 2023

Conversation

mofojed
Copy link
Member

@mofojed mofojed commented Sep 13, 2023

  • deephaven.ui plugin prototype initial checkin has some extremely basic cases implemented (Fixes Create deephaven.ui module, testing #51)
  • Needs my ui-plugin-prototype branch to work correctly (as that how the JS side is loading components): https://github.com/mofojed/web-client-ui/tree/ui-plugin-prototype
  • The examples in the plugins/ui/examples folder should work
  • Included DESIGN.md which is the discussion/notes from the google doc discussion
  • Added some TODO notes about things that require follow up
  • Install as you would other plugins

Implemented so far:

@mofojed mofojed self-assigned this Sep 13, 2023
- HTML element exports attributes
- Still need to wire it up to the render
- Add a bunch of functions for HTML elements
- TODO: Now need to output as json and encode it
- JS side has not been refactored yet
- Have a base Element type that can be used by HTML elements, other basic elements
- FunctionElement type handles Elements that can re-render with a function
- Separate components and object_types out into their own folder
- Motivated by keeping separation of concerns. Theoretically the render/elements could all by in their own package that is not dependent on `deephaven` package at all, which may be advantageous to separate out at some point (same rendering backend with different rendering frontend)
  - Would need to move the use_table_listener hook as well
@mofojed mofojed mentioned this pull request Sep 18, 2023
88 tasks
- Builds the array of exported objects
- Traverses through the tree and renders it
- Have not done HTML elements yet
- Now can wrap stuff in the html elements.
- Will need to add some test cases for components in general
- Will need to wire this up with Spectrum anyway
- Following example works:

```
import deephaven.ui as ui
from deephaven.ui import html, use_state

@ui.component
def stock_widget_table(source, default_sym="", default_exchange=""):
    sym, set_sym = use_state(default_sym)
    exchange, set_exchange = use_state(default_exchange)

    ti1 = ui.text_field(sym, on_change=set_sym)
    ti2 = ui.text_field(exchange, on_change=set_exchange)
    t1 = (
        source.where([f"sym=`{sym.upper()}`", f"exchange=`{exchange.upper()}`"])
        if sym and exchange
        else html.h1("Please enter Sym and Exchange Above")
    )

    return [ui.flex_row(ti1, ti2), t1]

import deephaven.plot.express as dx

stocks = dx.data.stocks()

swt = stock_widget_table(stocks, "", "")
```
- No callbacks from HTML yet
- Now should be able to do callbacks generically based on props
- Instead of re-using t, use a different variable name
@mofojed mofojed changed the title deephaven.ui plugin prototype initial checkin feat: deephaven.ui plugin prototype initial checkin Sep 28, 2023
Copy link
Collaborator

@mattrunyon mattrunyon left a comment

Choose a reason for hiding this comment

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

I only reviewed JS code

plugins/ui/src/js/src/DashboardPlugin.tsx Outdated Show resolved Hide resolved
plugins/ui/src/js/src/ElementPanel.tsx Outdated Show resolved Hide resolved
Comment on lines +56 to +58
? new JSONRPCServerAndClient(
new JSONRPCServer(),
new JSONRPCClient(request => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you explain a bit what jsonrpc brings to the table for us? Just curious as at a glance it looks like it's mostly just to wrap our existing widget rpc calls.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it provides an existing standard for sending messages/notifications between client/server. The grpc layer does not require a response per request, but with json-rpc there is a spec for a message that requires a response which is useful for callbacks.

plugins/ui/src/js/src/ElementPanel.tsx Show resolved Hide resolved
fetch(): Promise<JsWidget>;
}

function ElementPanel(props: ElementPanelProps) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I know it's still early, but jsdocs for the components and their purpose would be nice

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes - I'll include that in the next PR that moves a bunch of this logic - it was just in ElementPanel to use the convenient useDashboardPanel hook, but we'll need to put a lot of this logic in to the DashboardPlugin level so that we can open multiple panels.

plugins/ui/src/js/src/SpectrumElementUtils.ts Show resolved Hide resolved
plugins/ui/src/js/src/spectrum_wrappers/Slider.tsx Outdated Show resolved Hide resolved
plugins/ui/src/js/src/spectrum_wrappers/Slider.tsx Outdated Show resolved Hide resolved
plugins/ui/src/js/src/spectrum_wrappers/TextField.tsx Outdated Show resolved Hide resolved
Comment on lines 22 to 33
const debouncedOnChange = useDebouncedCallback(
propOnChange,
VALUE_CHANGE_DEBOUNCE
);

const onChange = useCallback(
newValue => {
setValue(newValue);
debouncedOnChange(newValue);
},
[debouncedOnChange]
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might make sense as a separate hook if we start using this over and over

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this and also event handlers will probably want some sort of hook or wrapper that we can re-use.

- Renamed `spectrum_wrappers` to just `spectrum`
- Externalize logging
  - Requires a change in web-client-ui as well
- Other cleanups
plugins/ui/examples/samples/double_table.py Outdated Show resolved Hide resolved
plugins/ui/examples/samples/stock_rollup.py Outdated Show resolved Hide resolved
plugins/ui/src/deephaven/ui/hooks/use_state.py Outdated Show resolved Hide resolved
plugins/ui/examples/samples/stock_widget_table.py Outdated Show resolved Hide resolved
plugins/ui/src/deephaven/ui/_internal/RenderContext.py Outdated Show resolved Hide resolved
plugins/ui/src/deephaven/ui/components/spectrum/flex.py Outdated Show resolved Hide resolved
plugins/ui/src/deephaven/ui/elements/FunctionElement.py Outdated Show resolved Hide resolved
plugins/ui/src/deephaven/ui/hooks/use_table_listener.py Outdated Show resolved Hide resolved
plugins/ui/src/deephaven/ui/renderer/NodeEncoder.py Outdated Show resolved Hide resolved
- Add typings to RenderContext
- Add comments in a couple places
- Fix up NodeEncoder so that it optimizes how items are added
- Code is already in the examples/README file
- There's a bunch of flex stuff that still needs to be cleaned up/figured out in the general layout of things.
plugins/ui/src/js/package.json Outdated Show resolved Hide resolved
jnumainville
jnumainville previously approved these changes Oct 5, 2023
@mofojed mofojed merged commit f753470 into deephaven:main Oct 5, 2023
2 checks passed
@mofojed mofojed mentioned this pull request Oct 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment