Skip to content

Commit

Permalink
WIP table with context items and submenus
Browse files Browse the repository at this point in the history
  • Loading branch information
mattrunyon committed Jun 6, 2024
1 parent ccc7298 commit fc9325c
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 11 deletions.
8 changes: 7 additions & 1 deletion plugins/ui/src/deephaven/ui/components/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ColumnPressCallback,
QuickFilterExpression,
RowPressCallback,
ContextMenuItem,
)


Expand All @@ -23,7 +24,9 @@ def table(
quick_filters: dict[ColumnName, QuickFilterExpression] | None = None,
show_quick_filters: bool = False,
show_search: bool = False,
context_actions: list[dict[str, str]] | None = None,
context_items: list[ContextMenuItem] | None = None,
context_column_header_items: list[ContextMenuItem] | None = None,
context_row_header_items: list[ContextMenuItem] | None = None,
) -> UITable:
"""
Customization to how a table is displayed, how it behaves, and listen to UI events.
Expand All @@ -49,6 +52,9 @@ def table(
quick_filters: The quick filters to apply to the table. Dictionary of column name to filter value.
show_quick_filters: Whether to show the quick filter bar by default.
show_search: Whether to show the search bar by default.
context_items: The context menu items to show when a cell is right clicked. May contain action items or submenu items.
context_column_header_items: The context menu items to show when a column header is right clicked. May contain action items or submenu items.
context_row_header_items: The context menu items to show when a row header is right clicked. May contain action items or submenu items.
"""
props = locals()
del props["table"]
Expand Down
14 changes: 7 additions & 7 deletions plugins/ui/src/js/src/elements/UITable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { dh } from '@deephaven/jsapi-types';
import Log from '@deephaven/log';
import { getSettings, RootState } from '@deephaven/redux';
import { EMPTY_ARRAY } from '@deephaven/utils';
import { UITableProps } from './UITableUtils';
import { UITableProps, wrapContextActions } from './UITableUtils';
import UITableMouseHandler from './UITableMouseHandler';

const log = Log.module('@deephaven/js-plugin-ui/UITable');
Expand All @@ -32,7 +32,7 @@ function UITable({
table: exportedTable,
showSearch: showSearchBar,
showQuickFilters,
contextActions,
contextItems,
}: UITableProps): JSX.Element | null {
const dh = useApi();
const [model, setModel] = useState<IrisGridModel>();
Expand Down Expand Up @@ -119,11 +119,11 @@ function UITable({

const onContextMenu = useCallback(
(data: IrisGridContextMenuData) =>
contextActions?.map(propAction => ({
...propAction,
action: () => propAction.action?.(data),
})) ?? [],
[contextActions]
wrapContextActions(contextItems ?? [], data).map(item => ({
group: 999999, // Put it at the bottom of the list
...item,
})),
[contextItems]
);

const irisGridProps = useMemo(
Expand Down
Empty file.
55 changes: 52 additions & 3 deletions plugins/ui/src/js/src/elements/UITableUtils.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import type { dh } from '@deephaven/jsapi-types';
import { ColumnName, DehydratedSort, RowIndex } from '@deephaven/iris-grid';
import type {
ColumnName,
DehydratedSort,
IrisGridContextMenuData,
RowIndex,
} from '@deephaven/iris-grid';
import type { ContextAction } from '@deephaven/components';
import { ELEMENT_KEY, ElementNode, isElementNode } from './ElementUtils';
import { ELEMENT_NAME, ElementName } from './ElementConstants';
import { ContextAction } from '@deephaven/components';

export type CellData = {
type: string;
Expand All @@ -19,6 +24,19 @@ export type ColumnIndex = number;

export type RowDataMap = Record<ColumnName, RowDataValue>;

export type UIContextItem = Omit<ContextAction, 'action' | 'actions'> & {
action?: (params: {
value: unknown;
text_value: string | null;
row_index: number | null;
column_index: number | null;
column_name: string;
is_column_header: boolean;
is_row_header: boolean;
}) => void;

actions?: UIContextItem[];
};
export interface UITableProps {
table: dh.WidgetExportedObject;
onCellPress?: (cellIndex: [ColumnIndex, RowIndex], data: CellData) => void;
Expand All @@ -35,7 +53,9 @@ export interface UITableProps {
sorts?: DehydratedSort[];
showSearch: boolean;
showQuickFilters: boolean;
contextActions?: ContextAction[];
contextItems?: UIContextItem[];
contextColumnHeaderItems?: UIContextItem[];
contextRowHeaderItems?: UIContextItem[];
[key: string]: unknown;
}

Expand All @@ -49,3 +69,32 @@ export function isUITable(obj: unknown): obj is UITableNode {
(obj as UITableNode)[ELEMENT_KEY] === ELEMENT_NAME.uiTable
);
}

/**
* Wraps context item actions from the server so they are called with the cell info.
* @param items The context items from the server
* @param data The context menu data to use for the context items
* @returns Context items with the UI actions wrapped so they receive the cell info
*/
export function wrapContextActions(
items: UIContextItem[],
data: IrisGridContextMenuData
): ContextAction[] {
return items.map(item => ({
...item,
action: item.action
? () => {
item.action?.({
value: data.value,
text_value: data.valueText,
row_index: data.rowIndex,
column_index: data.columnIndex,
column_name: data.column.name,
is_column_header: data.rowIndex == null,
is_row_header: data.columnIndex == null,
});
}
: undefined,
actions: item.actions ? wrapContextActions(item.actions, data) : undefined,
}));
}

0 comments on commit fc9325c

Please sign in to comment.