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: Implement python item_table_source #415

Merged
merged 13 commits into from
May 10, 2024
304 changes: 158 additions & 146 deletions plugins/ui/DESIGN.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions plugins/ui/src/deephaven/ui/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .list_view import list_view
from .list_action_group import list_action_group
from .list_action_menu import list_action_menu
from .item_table_source import item_table_source

from . import html

Expand All @@ -36,6 +37,7 @@
"icon",
"icon_wrapper",
"item",
"item_table_source",
"illustrated_message",
"list_view",
"list_action_group",
Expand Down
66 changes: 66 additions & 0 deletions plugins/ui/src/deephaven/ui/components/item_table_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from __future__ import annotations

from typing import Union, TypedDict, cast

from deephaven.table import Table, PartitionedTable

from .item import ItemElement
from .list_action_group import ListActionGroupElement
from .list_action_menu import ListActionMenuElement
from ..elements import Element
from ..types import ColumnName, Stringable

ListViewItem = Union[Stringable, ItemElement]
ListViewElement = Element


class ItemTableSource(TypedDict):
table: Table | PartitionedTable
key_column: ColumnName | None
label_column: ColumnName | None
description_column: ColumnName | None
icon_column: ColumnName | None
title_column: ColumnName | None
actions: ListActionGroupElement | ListActionMenuElement | None


def item_table_source(
table: Table | PartitionedTable,
key_column: ColumnName | None = None,
label_column: ColumnName | None = None,
description_column: ColumnName | None = None,
icon_column: ColumnName | None = None,
title_column: ColumnName | None = None,
actions: ListActionGroupElement | ListActionMenuElement | None = None,
) -> ItemTableSource:
"""
An item table source wraps a Table or PartitionedTable to provide additional information for
creating complex items from a table.
A PartitionedTable is only supported if the component itself supports a PartitionedTable as a child.
A PartitionedTable passed here will lead to the same behavior as passing
the PartitionedTable directly to a component, such as creating sections from the partitions in the case of a Picker.

Args:
table:
The table to use as the source of items.
key_column:
The column of values to use as item keys. Defaults to the first column.
label_column:
The column of values to display as primary text. Defaults to the key_column value.
description_column:
The column of values to display as descriptions.
icon_column:
The column of values to map to icons.
title_column:
Only valid if table is of type PartitionedTable.
The column of values to display as section names.
Should be the same for all values in the constituent Table.
If not specified, the section titles will be created from the key_columns of the PartitionedTable.
actions:
The action group or menus to render for all elements within the component, if supported.

Returns:
The item table source to pass as a child to a component that supports it.
"""

return cast(ItemTableSource, locals())
38 changes: 13 additions & 25 deletions plugins/ui/src/deephaven/ui/components/list_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,45 @@
from deephaven.table import Table

from .item import ItemElement
from .list_action_group import ListActionGroupElement
from .list_action_menu import ListActionMenuElement
from .item_table_source import ItemTableSource
from ..elements import BaseElement, Element
from .._internal.utils import create_props
from ..types import ColumnName, Stringable, Selection
from ..types import Stringable, Selection, SelectionMode

ListViewItem = Union[Stringable, ItemElement]
ListViewElement = Element


def list_view(
*children: ListViewItem | Table,
key_column: ColumnName | None = None,
label_column: ColumnName | None = None,
description_column: ColumnName | None = None,
icon_column: ColumnName | None = None,
actions: ListActionGroupElement | ListActionMenuElement | None = None,
*children: ListViewItem | Table | ItemTableSource,
default_selected_keys: Selection | None = None,
selected_keys: Selection | None = None,
selection_mode: SelectionMode | None = "MULTIPLE",
render_empty_state: Element | None = None,
on_selection_change: Callable[[Selection], None] | None = None,
on_change: Callable[[Selection], None] | None = None,
**props: Any,
) -> ListViewElement:
"""
A list view that can be used to create a list of items. Children should be one of two types:
A list view that can be used to create a list of items. Children should be one of three types:
1. If children are of type `ListViewItem`, they are the list items.
2. If children are of type `Table`, the values in the table are the list items.
There can only be one child, the `Table`.

The first column is used as the key and label by default.
3. If children are of type ItemTableSource, complex items are created from the source.
There can only be one child, the `ItemTableSource`.
Supported `ItemTableSource` arguments are `key_column`, `label_column`, `description_column`,
`icon_column`, and `actions`.

Args:
*children: The options to render within the list_view.
key_column:
Only valid if children are of type Table.
The column of values to use as item keys. Defaults to the first column.
label_column:
Only valid if children are of type Table.
The column of values to display as primary text. Defaults to the key_column value.
description_column:
Only valid if children are of type Table.
The column of values to display as descriptions.
icon_column: Only valid if children are of type Table.
The column of values to map to icons.
actions:
Only valid if children are of type Table.
The action group or menus to render for all elements within the list view.
default_selected_keys:
The initial selected keys in the collection (uncontrolled).
selected_keys:
The currently selected keys in the collection (controlled).
selection_mode:
jnumainville marked this conversation as resolved.
Show resolved Hide resolved
Can be `MULTIPLE` to allow multiple selection, `SINGLE` to allow only single selection,
or None to allow no selection.
render_empty_state:
Sets what the `list_view` should render when there is no content to display.
on_selection_change:
Expand Down
42 changes: 14 additions & 28 deletions plugins/ui/src/deephaven/ui/components/picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,39 @@

from deephaven.table import Table, PartitionedTable
from .section import SectionElement, PickerItem
from .item_table_source import ItemTableSource
from ..elements import BaseElement
from .._internal.utils import create_props
from ..types import ColumnName, Key
from ..types import Key

PickerElement = BaseElement


def picker(
*children: PickerItem | SectionElement | Table | PartitionedTable,
key_column: ColumnName | None = None,
label_column: ColumnName | None = None,
description_column: ColumnName | None = None,
icon_column: ColumnName | None = None,
title_column: ColumnName | None = None,
*children: PickerItem | SectionElement | Table | PartitionedTable | ItemTableSource,
default_selected_key: Key | None = None,
selected_key: Key | None = None,
on_selection_change: Callable[[Key], None] | None = None,
on_change: Callable[[Key], None] | None = None,
**props: Any,
) -> PickerElement:
"""
A picker that can be used to select from a list. Children should be one of four types:
If children are of type PickerItem, they are the dropdown options.
If children are of type SectionElement, they are the dropdown sections.
If children are of type Table, the values in the table are the dropdown options.
A picker that can be used to select from a list. Children should be one of five types:
1. If children are of type PickerItem, they are the dropdown options.
2. If children are of type SectionElement, they are the dropdown sections.
3. If children are of type Table, the values in the table are the dropdown options.
There can only be one child, the Table.
If children are of type PartitionedTable, the values in the table are the dropdown options
The first column is used as the key and label by default.
4. If children are of type PartitionedTable, the values in the table are the dropdown options
and the partitions create multiple sections. There can only be one child, the PartitionedTable.
The first column is used as the key and label by default.
5. If children are of type ItemTableSource, complex items are created from the source.
There can only be one child, the ItemTableSource.
Supported ItemTableSource arguments are `key_column`, `label_column`, `description_column`,
`icon_column`, and `title_column`.

Args:
*children: The options to render within the picker.
key_column:
Only valid if children are of type Table or PartitionedTable.
The column of values to use as item keys. Defaults to the first column.
label_column:
Only valid if children are of type Table or PartitionedTable.
The column of values to display as primary text. Defaults to the key_column value.
description_column:
Only valid if children are of type Table or PartitionedTable.
The column of values to display as descriptions.
icon_column: Only valid if children are of type Table or PartitionedTable.
The column of values to map to icons.
title_column:
Only valid if children is of type PartitionedTable.
The column of values to display as section names.
Should be the same for all values in the constituent Table.
If not specified, the section titles will be created from the key_columns of the PartitionedTable.
default_selected_key:
The initial selected key in the collection (uncontrolled).
selected_key:
Expand Down
3 changes: 2 additions & 1 deletion plugins/ui/src/deephaven/ui/types/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ class RowDataValue(CellData):
ColumnData = List[Any]
TableData = Dict[ColumnName, ColumnData]
SearchMode = Literal["SHOW", "HIDE", "DEFAULT"]
SelectionMode = Literal["CELL", "ROW", "COLUMN"]
SelectionArea = Literal["CELL", "ROW", "COLUMN"]
SelectionMode = Literal["SINGLE", "MULTIPLE"]
jnumainville marked this conversation as resolved.
Show resolved Hide resolved
Sentinel = Any
TransformedData = Any
StringSortDirection = Literal["ASC", "DESC"]
Expand Down
Loading