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: Merge remote-tracking branch 'origin/main' into feature/core-plugins-refactor #2006

Conversation

mofojed
Copy link
Member

@mofojed mofojed commented May 13, 2024

  • Ran git merge origin/main, fixed conflicts

mofojed and others added 30 commits April 18, 2024 12:39
…aders are not 0 (deephaven#1927)

- Shouldn't throw in those cases, we should handle when calculatedSizes
is empty
- Found when using out
[deephaven-doom](https://github.com/mofojed/deephaven-doom), couldn't
resize/move columns like expected
- Also tested in the styleguide - dragging columns when there were row
headers visible did not work correctly
- ListView components
- Smart item tooltip handling (only show when text is overflowing)
- Split out some shared util code from Picker
- Wrapped Text, View, and Heading in forwardRef

**Testing**
This can be tested using this PR:
deephaven/deephaven-plugins#408 . To make
TypeScript happy, you can install DHC as an alpha via:

```sh
npm run update-dh-packages -- --scope=@deephaven/js-plugin-ui -- 0.72.1-alpha-list-view.38
```

BREAKING CHANGE: `LIST_VIEW_ROW_HEIGHT` number constant replaced with
dictionary `LIST_VIEW_ROW_HEIGHTS`
…ven#1946)

- set responsive config to true which allows plots to properly grow and
shrink
- removed unnecessary useResizeHandler (which only watches window), as
we have our own observer
- fixed failing test by changing locator to plotly parent container.
Responsive setting has an absolutely positioned child that makes the
other locator have zero height,

Tested with the following script, and resizing golden-layout panels both
vertically and horizontally and resizing browser window horizontally and
vertically.

```py
from deephaven import ui, empty_table
from deephaven.plot import express as dx

t = empty_table(100).update(["x = i", "y = i"])
p = dx.line(t, x="x", y="y")

@ui.component
def common_example():
    return ui.panel(
        ui.flex(
            ui.text_field(label="Text Field"),
            ui.text_field(label="Text Field"),
            ui.text_field(label="Text Field"),
        ),
        t,
        p
    )

ui_common_example = common_example()


@ui.component
def common_example_row():
    return ui.panel(
        ui.flex(
            ui.text_field(label="Text Field"),
            ui.text_field(label="Text Field"),
            ui.text_field(label="Text Field"),
            direction="column"
        ),
        t,
        p,
        direction="row"
    )

ui_common_example_row = common_example_row()
```
…haven#1951)

Fixes deephaven#1794
- Label home as "vsTerminal Code Studio"
- Make it part of the navtab list to get an active state
- Allow navtab list to accept an Icon | JSX.Element
- Adds deephaven#1784 
- Add an event to see if download was triggered
Needed for deephaven/deephaven-plugins#215

Doesn't support multiple dashboards being opened in one embed, but some
of the groundwork is there and we don't support multiple dashboards from
a single widget anyway yet.
Closes deephaven#1867

Tested in Enterprise using steps from DH-16595 - created a partitioned
table and set ACL to `nullFilterGenerator()` to get the `null` value in
the partition column. Creating a partitioned table with a `null` in the
partition column doesn't seem possible with `db.addTablePartition` in
Enterprise.

```
t=db.t("LearnDeephaven", "StockTrades").where()
db.addPartitionedTableDefinition("<namespace>", "partTable", "Date", t.getDefinition())
test = db.t("<namespace>" , "partTable")

// Set Column ACL on `partTable` to `new NullFilterGenerator()` in swing

test = db.t("<namespace>" , "partTable")
```
![Screenshot 2024-04-23 at 5 26
43 PM](https://github.com/deephaven/web-client-ui/assets/2853653/bbd65305-4616-416d-8af3-96dadcc21fa1)


Core+ Groovy console:
```
t = emptyTable(1).update("X=(String)null","Y=ii").partitionBy("X")
```
![Screenshot 2024-04-23 at 5 23
55 PM](https://github.com/deephaven/web-client-ui/assets/2853653/0564a626-97fa-46d9-8920-200eda19c533)

---------

Co-authored-by: Mike Bender <[email protected]>
NOTE: This PR depends on
deephaven/deephaven-plugins#424 in order for
element type checks to work for `Item`, `Text`, `Section`, etc.

- Refactored non-jsapi Picker to support JSX children with minimal
wrapping instead of having to normalize items (deephaven#1890 should do the same
for ListView, and we should be able to delete some of the normalization
code)
- Updated scroll position logic to be able to traverse JSX elements
- Disable initial scrolling when children contain descriptions or
sections

**Testing**
This illustrates different configurations and shows how initial scroll
behavior differs for Pickers with plain items, descriptions, or
sections:

```python
import deephaven.ui as ui
from math import floor
import datetime

# Ticking table with initial row count of 200 that adds a row every second
initial_row_count=1000
items_table = time_table("PT1S", start_time=datetime.datetime.now() - datetime.timedelta(seconds=initial_row_count)).update([
    "Id=new Integer(i)",
    "Display=new String(`Display `+i)",
])

@ui.component
def pickers():
    value, set_value = ui.use_state('2SSS')

    def handle_change(v):
        print(v)
        set_value(v)

    on_change = ui.use_callback(handle_change, [])

    # Picker with text options
    text = ui.picker(
        label="Text",
        children=[
            'Text 1',
            'Text 2',
            'Text 3'
        ]
    )

    # Picker with boolean options
    boolean = ui.picker(
        label="Boolean",
        children=[
            True,
            False
        ]
    )

    # Picker with numeric options
    numeric = ui.picker(
        label="Numeric",
        children=[
            10,
            20,
            30
        ]
    )

    ################ Icons #######################################

    # Icons
    icons = ui.picker(
        label = "Icons",
        children = [
            item_with_icon('Add', 'vsAdd'),
            item_with_icon('Remove', 'vsRemove'),
        ]
    )

    # Icons (default selection)
    icons_default_selection = ui.picker(
        label = "Icons (default selection)",
        default_selected_key="3GGG",
        children = list(map(
            lambda args : item(args[1]) if args[0] % 7 > 0 else item_with_icon(args[1], 'vsAccount'), 
            enumerate(generate_item_texts(0, 500))))
    )

     # Icons (controlled)
    icons_controlled = ui.picker(
        label = "Icons (controlled)",
        selected_key=value,
        on_change=on_change,
        children = list(map(
            lambda args : item(args[1]) if args[0] % 7 > 0 else item_with_icon(args[1], 'vsAccount'), 
            enumerate(generate_item_texts(0, 500))))
    )

    ################ Descriptions #######################################

    # Descriptions (default selection)
    descriptions = ui.picker(
        label = "Descriptions",
        children = list(map(lambda txt : item(txt, True), generate_item_texts(0, 500)))
    )

    # Descriptions (default selection)
    descriptions_default_selection = ui.picker(
        label = "Descriptions (default selection)",
        default_selected_key="3GGG",
        children = list(map(lambda txt : item(txt, True), generate_item_texts(0, 500)))
    )

    # Descriptions (controlled)
    descriptions_controlled = ui.picker(
        label = "Descriptions (controlled)",
        selected_key=value,
        on_change=on_change,
        children = list(map(lambda txt : item(txt, True), generate_item_texts(0, 500)))
    )

    ################ Sections #######################################

    # Sections
    sections = ui.picker(
        label = "Sections (default selection)",
        children = [
            section(x, i * 10, i * 10 + 9) for i, x in enumerate(generate_item_texts(0, 19))
        ]
    )

    # Sections (default selection)
    sections_default_selection = ui.picker(
        label = "Sections (default selection)",
        default_selected_key = "3GGG",
        children = [
            section(x, i * 10, i * 10 + 9) for i, x in enumerate(generate_item_texts(0, 19))
        ]
    )

    # Sections (controlled)
    sections_controlled = ui.picker(
        label = "Sections (controlled)",
        selected_key=value,
        on_change=on_change,
        children = [
            section(x, i * 10, i * 10 + 9) for i, x in enumerate(generate_item_texts(0, 19))
        ]
    )

    ################ Tables #######################################

    table_value, set_table_value = ui.use_state('Display 824')

    # Uncontrolled table with default selection
    table = ui.picker(
        items_table,
        key_column="Display",
        label_column="Display",
        label="Table",
    )

    # Uncontrolled table with default selection
    table_default_selection = ui.picker(
        items_table,
        key_column="Display",
        label_column="Display",
        label="Table (default selection)",
        default_selected_key="Display 86",
    )

    # Controlled table
    table_controlled = ui.picker(
        items_table,
        key_column="Display",
        label_column="Display",
        label="Table (controlled)",
        on_selection_change=set_table_value,
        selected_key=table_value,
    )

    return ui.flex(
        direction="column",
        UNSAFE_style={"overflow":"scroll"},
        children = [
            ui.heading("Basic", margin=0),
            ui.flex(
                direction='row',
                children=[
                    text,
                    boolean,
                    numeric,
                ]
            ),
            ui.heading("Icons", margin=0),
            ui.flex(
                direction='row',
                children=[
                    icons,
                    icons_default_selection,
                    icons_controlled,
                ]
            ),
            ui.heading("Descriptions", margin=0),
            ui.flex(
                direction='row',
                children=[
                    descriptions,
                    descriptions_default_selection,
                    descriptions_controlled,
                ]
            ),
            ui.heading("Sections", margin=0),
            ui.flex(
                direction='row',
                children=[
                    sections,
                    sections_default_selection,
                    sections_controlled,
                ]
            ),
            ui.heading("Table", margin=0),
            ui.flex(
                direction='row',
                children=[
                    table,
                    table_default_selection,
                    table_controlled,
                ]
            )
        ],
    )

pick = pickers()

################ Helpers #######################################

# Generate a list of unique item text for a start / stop range
def generate_item_texts(start, stop):
    characters = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    size = len(characters)
    return [str(floor((i + start) / size)) + (characters[x % size] * 3) for i, x in enumerate(range(start, stop))]

@ui.component
def item(txt, include_description=False):
    return ui.item(
        ui.text(txt, key="label"),
        ui.text("Description " + txt, key="description", slot="description"),
        # key=txt,
        text_value=txt
    ) if include_description else ui.item(txt, text_value=txt)

@ui.component
def item_with_icon(txt, icon):
    return ui.item(
        text_value=txt,
        children=[
            ui.icon(icon),
            txt,
        ]
    )

@ui.component
def section(txt, start, end):
    return ui.section(
        title = "Section " + txt,
        children = list(map(lambda txt : item(txt), generate_item_texts(start, end)))
    )
```

resolves deephaven#1935
- Adds deephaven#1931 
  - Add new context menu option for panels
  - Give IDs to stacks and helper function to get stacks by ID
  - Add ability to open component to specific stack
  - Fix unit tests related to IDs and layouts, added E2E tests

---------

Co-authored-by: Mike Bender <[email protected]>
- Adds deephaven#1933 
- Shards Playwright E2E tests by browser
  - Webkit into 2 shards because it runs slower
- Adds deephaven#1902
- Use `@fontsource` instead of GitHub as source
- Lock to Fira Sans to 5.0.20 and Fira Mono to 5.0.13 to prevent kerning
problems

---------

Co-authored-by: Don <[email protected]>
- Adds deephaven#1966 
- Disables the download check for Webkit
…en#1965)

- Added to the StyleGuide as well
- Displays errors in a textarea, with a copy button and an expand button
)

Updated @deephaven/jsapi-types to 1.0.0-dev0.34.0

resolves deephaven#1974
This example shows both basic and table data sources.
```python
import deephaven.ui as ui


@ui.component
def ui_list_view():
    value, set_value = ui.use_state(["Text 2"])

    text = ui.text("Selection: " + ", ".join(map(str, value)), grid_column="span 2")

    # list_view with text children
    lv = ui.list_view(
        "Text 1",
        "Text 2",
        "Text 3",
        # min_height=1,
        aria_label="List View",
        on_change=set_value,
        selected_keys=value,
    )

    # list_view with item children
    lv2 = ui.list_view(
        ui.item("Item 1", key="Text 1"),
        ui.item("Item 2", key="Text 2"),
        ui.item("Item 3", key="Text 3"),
        aria_label="List View 2",
        on_change=set_value,
        selected_keys=value,
    )
    
    return ui.grid(
        text,
        lv,
        lv2,
        columns="repeat(2, 1fr)",
        rows="min-content",
        height="100%"
    )


lv = ui_list_view()

####################################
import deephaven.ui as ui
from deephaven import time_table
import datetime

icon_names = ['vsAccount']

# Ticking table with initial row count of 200 that adds a row every second
initial_row_count=2000
columns = [
    "Id=new Integer(i)",
    "Display=new String(`Display `+i)",
    "Description=new String(`Description `+i)",
    "Icon=(String) icon_names[0]"
]
# column_types_ticking = time_table("PT1S", start_time=datetime.datetime.now() - datetime.timedelta(seconds=initial_row_count)).update([
#     columns
# )
column_types = empty_table(initial_row_count).update(columns)

@ui.component
def labeled_lv(label, *args, **kwargs):
    return ui.flex(
        ui.text(label),
        ui.list_view(
            *args,
            **kwargs
        ),
        direction="column",
        flex=1,
        min_width=0,
    )

@ui.component
def ui_list_view_table():
    value, set_value = ui.use_state([2, 4, 5])

    lv = labeled_lv(
        "Compact",
        column_types,
        max_height=5000,
        density="compact",
        key_column="Id",
        label_column="Display",
        icon_column="Icon",
        aria_label="List View",
        on_change=set_value,
        selected_keys=value,
    )

    lv2 = labeled_lv(
        "Regular",
        column_types,
        max_height=5000,
        density="regular",
        key_column="Id",
        label_column="Display",
        icon_column="Icon",
        aria_label="List View 2",
        on_change=set_value,
        selected_keys=value,
    )

    lv3 = labeled_lv(
        "Spacious",
        column_types,
        max_height=5000,
        density="spacious",
        key_column="Id",
        label_column="Display",
        icon_column="Icon",
        aria_label="List View 3",
        on_change=set_value,
        selected_keys=value,
    )

    text = ui.text("Selection: " + ", ".join(map(str, value)))

    return ui.flex(
        ui.flex(
            lv,
            lv2,
            lv3,
            direction="row",
            gap=10,
        ),
        text,
        direction="column",
    )

lv_table = ui_list_view_table()
```

resolves deephaven#1890

---------

Co-authored-by: Don McKenzie <[email protected]>
Downgraded Spectrum to 3.33.1 to fix Combobox scrolling.

resolves deephaven#1976
- Benchmark results:
https://www.npmjs.com/package/fast-deep-equal#performance-benchmark
- Tested to make sure notebook lag was reduced (typing in a Notebook
with a dashboard with many components)
- Continue using `deep-equal` package in the `IrisGridUtils.test.ts`, as
that test requires the `strict: true`. It is only included as a
devDependency
- We were checking the diff of the layouts on each keystroke
- DashboardLayout should debounce checking that diff
- Tested by displaying FPS counter, having a Code Studio with a bunch of
tables in it, adding a notebook, and then typing in it. FPS is much
higher after the change
Automated changes by
[create-pull-request](https://github.com/peter-evans/create-pull-request)
GitHub action

Co-authored-by: mofojed <[email protected]>
…ttings redux selector (deephaven#1982)

Discovered as part of deephaven#1977 investigation. Typing in a notebook triggers
a workspace update, which was triggering all tables to re-render.
Removed deprecated dependeny of workspace from iris-grid.

Further settings is derived from workspace and returns a new settings
object. Iris-grid depends on settings, but the object had no changes.
Memoize the selector so it always returns the same object if settings
haven't changed.

Removes ~100ms of lag that was occuring 400ms after the debounce of
notebook key press events.

BREAKING CHANGE: getPluginContent deprecatedProps have been removed from
iris-grid
…deephaven#1983)

Removed orphaned code that used to do things, but now doesn't do
anything but update an unused isFocused state variable. This was causing
an additional re-render on focus when state was then updated.
Wired up ListView props I missed on refactor.
…1994)

fixes root issue of DH-16914

I published this as an alpha for DHE testing: 

[0.76.1-alpha-optimize-selection-get-key.0](https://www.npmjs.com/package/@deephaven/react-hooks/v/0.76.1-alpha-optimize-selection-get-key.0)

BREAKING CHANGE: @deephaven/react-hooks:
`SelectionUtils.optimizeSelection` and `useMappedSelection` require
additional `getKey` arg
mattrunyon and others added 6 commits May 7, 2024 17:47
Resolves deephaven#1990
- Add functionality to close dashboard tab with middle mouse click by
specifying onAuxClick event
- Create NavBar component test cases that test changes
)

Fixes deephaven/deephaven-plugins#435

Does not fix the issue in embed-widget. I think that should be a
separate ticket. I'll keep
deephaven#1964 open for tracking
that if that seems fine

Tested by creating a dh.ui component that included a table and then
changed the formatter settings. Tried global column formats too (the
formats for specifically named columns)

Looks like ui.table already loads these settings, so this will fix for
normal tables.
…1987)

- Each GridRenderer had an independent cache for checking various colour
operations, instead use a shared cache
- Grids are likely to share the same colours because they have similar
themes anyway
- Improves performance when opening dashboards with lots of grids
- Add a little blur to overlays, so they're easier to read when on top
of complex backgrounds
- Change the colour and transparency level of the error background
@mofojed mofojed requested a review from mattrunyon May 13, 2024 15:10
@mofojed mofojed self-assigned this May 13, 2024
@mofojed mofojed requested review from bmingles and removed request for mattrunyon May 13, 2024 15:10
@mofojed mofojed changed the title Merge remote-tracking branch 'origin/main' into feature/core-plugins-refactor feat: Merge remote-tracking branch 'origin/main' into feature/core-plugins-refactor May 13, 2024
@mofojed mofojed requested a review from mattrunyon May 13, 2024 19:01
Copy link
Contributor

@bmingles bmingles left a comment

Choose a reason for hiding this comment

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

+1

@mofojed mofojed merged commit c50d0ae into deephaven:feature/core-plugins-refactor May 14, 2024
9 checks passed
@mofojed mofojed deleted the 2024-05-13-core-plugins-refactor-main-update branch May 14, 2024 13:17
@github-actions github-actions bot locked and limited conversation to collaborators May 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants