From 454c7dca595ac4395efcd881bae160de9a68669d Mon Sep 17 00:00:00 2001 From: Marek Mihok Date: Thu, 23 Nov 2023 08:52:46 +0100 Subject: [PATCH] feat: Add name attribute to ui.stats #2197 (#2205) --- py/h2o_lightwave/h2o_lightwave/types.py | 30 +++++++++++++++++++ py/h2o_lightwave/h2o_lightwave/ui.py | 9 ++++++ py/h2o_wave/h2o_wave/types.py | 30 +++++++++++++++++++ py/h2o_wave/h2o_wave/ui.py | 9 ++++++ r/R/ui.R | 20 ++++++++++--- .../resources/templates/wave-components.xml | 9 ++++-- .../vscode-extension/component-snippets.json | 6 ++-- ui/src/stats.tsx | 4 +++ ui/src/tall_stats.tsx | 4 ++- 9 files changed, 110 insertions(+), 11 deletions(-) diff --git a/py/h2o_lightwave/h2o_lightwave/types.py b/py/h2o_lightwave/h2o_lightwave/types.py index 80f892cd71..8887cc6b1e 100644 --- a/py/h2o_lightwave/h2o_lightwave/types.py +++ b/py/h2o_lightwave/h2o_lightwave/types.py @@ -5842,12 +5842,14 @@ def __init__( caption: Optional[str] = None, icon: Optional[str] = None, icon_color: Optional[str] = None, + name: Optional[str] = None, ): _guard_scalar('Stat.label', label, (str,), False, False, False) _guard_scalar('Stat.value', value, (str,), False, True, False) _guard_scalar('Stat.caption', caption, (str,), False, True, False) _guard_scalar('Stat.icon', icon, (str,), False, True, False) _guard_scalar('Stat.icon_color', icon_color, (str,), False, True, False) + _guard_scalar('Stat.name', name, (str,), False, True, False) self.label = label """The label for the metric.""" self.value = value @@ -5858,6 +5860,8 @@ def __init__( """An optional icon, displayed next to the label.""" self.icon_color = icon_color """The color of the icon.""" + self.name = name + """An identifying name for this item.""" def dump(self) -> Dict: """Returns the contents of this object as a dict.""" @@ -5866,12 +5870,14 @@ def dump(self) -> Dict: _guard_scalar('Stat.caption', self.caption, (str,), False, True, False) _guard_scalar('Stat.icon', self.icon, (str,), False, True, False) _guard_scalar('Stat.icon_color', self.icon_color, (str,), False, True, False) + _guard_scalar('Stat.name', self.name, (str,), False, True, False) return _dump( label=self.label, value=self.value, caption=self.caption, icon=self.icon, icon_color=self.icon_color, + name=self.name, ) @staticmethod @@ -5887,17 +5893,21 @@ def load(__d: Dict) -> 'Stat': _guard_scalar('Stat.icon', __d_icon, (str,), False, True, False) __d_icon_color: Any = __d.get('icon_color') _guard_scalar('Stat.icon_color', __d_icon_color, (str,), False, True, False) + __d_name: Any = __d.get('name') + _guard_scalar('Stat.name', __d_name, (str,), False, True, False) label: str = __d_label value: Optional[str] = __d_value caption: Optional[str] = __d_caption icon: Optional[str] = __d_icon icon_color: Optional[str] = __d_icon_color + name: Optional[str] = __d_name return Stat( label, value, caption, icon, icon_color, + name, ) @@ -5922,12 +5932,14 @@ def __init__( inset: Optional[bool] = None, width: Optional[str] = None, visible: Optional[bool] = None, + name: Optional[str] = None, ): _guard_vector('Stats.items', items, (Stat,), False, False, False) _guard_enum('Stats.justify', justify, _StatsJustify, True) _guard_scalar('Stats.inset', inset, (bool,), False, True, False) _guard_scalar('Stats.width', width, (str,), False, True, False) _guard_scalar('Stats.visible', visible, (bool,), False, True, False) + _guard_scalar('Stats.name', name, (str,), False, True, False) self.items = items """The individual stats to be displayed.""" self.justify = justify @@ -5938,6 +5950,8 @@ def __init__( """The width of the stats, e.g. '100px'.""" self.visible = visible """True if the component should be visible. Defaults to True.""" + self.name = name + """An identifying name for this component.""" def dump(self) -> Dict: """Returns the contents of this object as a dict.""" @@ -5946,12 +5960,14 @@ def dump(self) -> Dict: _guard_scalar('Stats.inset', self.inset, (bool,), False, True, False) _guard_scalar('Stats.width', self.width, (str,), False, True, False) _guard_scalar('Stats.visible', self.visible, (bool,), False, True, False) + _guard_scalar('Stats.name', self.name, (str,), False, True, False) return _dump( items=[__e.dump() for __e in self.items], justify=self.justify, inset=self.inset, width=self.width, visible=self.visible, + name=self.name, ) @staticmethod @@ -5967,17 +5983,21 @@ def load(__d: Dict) -> 'Stats': _guard_scalar('Stats.width', __d_width, (str,), False, True, False) __d_visible: Any = __d.get('visible') _guard_scalar('Stats.visible', __d_visible, (bool,), False, True, False) + __d_name: Any = __d.get('name') + _guard_scalar('Stats.name', __d_name, (str,), False, True, False) items: List[Stat] = [Stat.load(__e) for __e in __d_items] justify: Optional[str] = __d_justify inset: Optional[bool] = __d_inset width: Optional[str] = __d_width visible: Optional[bool] = __d_visible + name: Optional[str] = __d_name return Stats( items, justify, inset, width, visible, + name, ) @@ -12713,15 +12733,19 @@ def __init__( self, box: str, items: List[Stat], + name: Optional[str] = None, commands: Optional[List[Command]] = None, ): _guard_scalar('TallStatsCard.box', box, (str,), False, False, False) _guard_vector('TallStatsCard.items', items, (Stat,), False, False, False) + _guard_scalar('TallStatsCard.name', name, (str,), False, True, False) _guard_vector('TallStatsCard.commands', commands, (Command,), False, True, False) self.box = box """A string indicating how to place this component on the page.""" self.items = items """The individual stats to be displayed.""" + self.name = name + """An identifying name for this component.""" self.commands = commands """Contextual menu commands for this component.""" @@ -12729,11 +12753,13 @@ def dump(self) -> Dict: """Returns the contents of this object as a dict.""" _guard_scalar('TallStatsCard.box', self.box, (str,), False, False, False) _guard_vector('TallStatsCard.items', self.items, (Stat,), False, False, False) + _guard_scalar('TallStatsCard.name', self.name, (str,), False, True, False) _guard_vector('TallStatsCard.commands', self.commands, (Command,), False, True, False) return _dump( view='tall_stats', box=self.box, items=[__e.dump() for __e in self.items], + name=self.name, commands=None if self.commands is None else [__e.dump() for __e in self.commands], ) @@ -12744,14 +12770,18 @@ def load(__d: Dict) -> 'TallStatsCard': _guard_scalar('TallStatsCard.box', __d_box, (str,), False, False, False) __d_items: Any = __d.get('items') _guard_vector('TallStatsCard.items', __d_items, (dict,), False, False, False) + __d_name: Any = __d.get('name') + _guard_scalar('TallStatsCard.name', __d_name, (str,), False, True, False) __d_commands: Any = __d.get('commands') _guard_vector('TallStatsCard.commands', __d_commands, (dict,), False, True, False) box: str = __d_box items: List[Stat] = [Stat.load(__e) for __e in __d_items] + name: Optional[str] = __d_name commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands] return TallStatsCard( box, items, + name, commands, ) diff --git a/py/h2o_lightwave/h2o_lightwave/ui.py b/py/h2o_lightwave/h2o_lightwave/ui.py index 13c88404c2..9967255f1d 100644 --- a/py/h2o_lightwave/h2o_lightwave/ui.py +++ b/py/h2o_lightwave/h2o_lightwave/ui.py @@ -2159,6 +2159,7 @@ def stat( caption: Optional[str] = None, icon: Optional[str] = None, icon_color: Optional[str] = None, + name: Optional[str] = None, ) -> Stat: """Create a stat (a label-value pair) for displaying a metric. @@ -2168,6 +2169,7 @@ def stat( caption: The caption displayed below the primary value. icon: An optional icon, displayed next to the label. icon_color: The color of the icon. + name: An identifying name for this item. Returns: A `h2o_wave.types.Stat` instance. """ @@ -2177,6 +2179,7 @@ def stat( caption, icon, icon_color, + name, ) @@ -2186,6 +2189,7 @@ def stats( inset: Optional[bool] = None, width: Optional[str] = None, visible: Optional[bool] = None, + name: Optional[str] = None, ) -> Component: """Create a set of stats laid out horizontally. @@ -2195,6 +2199,7 @@ def stats( inset: Whether to display the stats with a contrasting background. width: The width of the stats, e.g. '100px'. visible: True if the component should be visible. Defaults to True. + name: An identifying name for this component. Returns: A `h2o_wave.types.Stats` instance. """ @@ -2204,6 +2209,7 @@ def stats( inset, width, visible, + name, )) @@ -4507,6 +4513,7 @@ def tall_series_stat_card( def tall_stats_card( box: str, items: List[Stat], + name: Optional[str] = None, commands: Optional[List[Command]] = None, ) -> TallStatsCard: """Create a vertical label-value pairs collection. Icon in `ui.stat` is not yet supported in this card. @@ -4514,6 +4521,7 @@ def tall_stats_card( Args: box: A string indicating how to place this component on the page. items: The individual stats to be displayed. + name: An identifying name for this component. commands: Contextual menu commands for this component. Returns: A `h2o_wave.types.TallStatsCard` instance. @@ -4521,6 +4529,7 @@ def tall_stats_card( return TallStatsCard( box, items, + name, commands, ) diff --git a/py/h2o_wave/h2o_wave/types.py b/py/h2o_wave/h2o_wave/types.py index 80f892cd71..8887cc6b1e 100644 --- a/py/h2o_wave/h2o_wave/types.py +++ b/py/h2o_wave/h2o_wave/types.py @@ -5842,12 +5842,14 @@ def __init__( caption: Optional[str] = None, icon: Optional[str] = None, icon_color: Optional[str] = None, + name: Optional[str] = None, ): _guard_scalar('Stat.label', label, (str,), False, False, False) _guard_scalar('Stat.value', value, (str,), False, True, False) _guard_scalar('Stat.caption', caption, (str,), False, True, False) _guard_scalar('Stat.icon', icon, (str,), False, True, False) _guard_scalar('Stat.icon_color', icon_color, (str,), False, True, False) + _guard_scalar('Stat.name', name, (str,), False, True, False) self.label = label """The label for the metric.""" self.value = value @@ -5858,6 +5860,8 @@ def __init__( """An optional icon, displayed next to the label.""" self.icon_color = icon_color """The color of the icon.""" + self.name = name + """An identifying name for this item.""" def dump(self) -> Dict: """Returns the contents of this object as a dict.""" @@ -5866,12 +5870,14 @@ def dump(self) -> Dict: _guard_scalar('Stat.caption', self.caption, (str,), False, True, False) _guard_scalar('Stat.icon', self.icon, (str,), False, True, False) _guard_scalar('Stat.icon_color', self.icon_color, (str,), False, True, False) + _guard_scalar('Stat.name', self.name, (str,), False, True, False) return _dump( label=self.label, value=self.value, caption=self.caption, icon=self.icon, icon_color=self.icon_color, + name=self.name, ) @staticmethod @@ -5887,17 +5893,21 @@ def load(__d: Dict) -> 'Stat': _guard_scalar('Stat.icon', __d_icon, (str,), False, True, False) __d_icon_color: Any = __d.get('icon_color') _guard_scalar('Stat.icon_color', __d_icon_color, (str,), False, True, False) + __d_name: Any = __d.get('name') + _guard_scalar('Stat.name', __d_name, (str,), False, True, False) label: str = __d_label value: Optional[str] = __d_value caption: Optional[str] = __d_caption icon: Optional[str] = __d_icon icon_color: Optional[str] = __d_icon_color + name: Optional[str] = __d_name return Stat( label, value, caption, icon, icon_color, + name, ) @@ -5922,12 +5932,14 @@ def __init__( inset: Optional[bool] = None, width: Optional[str] = None, visible: Optional[bool] = None, + name: Optional[str] = None, ): _guard_vector('Stats.items', items, (Stat,), False, False, False) _guard_enum('Stats.justify', justify, _StatsJustify, True) _guard_scalar('Stats.inset', inset, (bool,), False, True, False) _guard_scalar('Stats.width', width, (str,), False, True, False) _guard_scalar('Stats.visible', visible, (bool,), False, True, False) + _guard_scalar('Stats.name', name, (str,), False, True, False) self.items = items """The individual stats to be displayed.""" self.justify = justify @@ -5938,6 +5950,8 @@ def __init__( """The width of the stats, e.g. '100px'.""" self.visible = visible """True if the component should be visible. Defaults to True.""" + self.name = name + """An identifying name for this component.""" def dump(self) -> Dict: """Returns the contents of this object as a dict.""" @@ -5946,12 +5960,14 @@ def dump(self) -> Dict: _guard_scalar('Stats.inset', self.inset, (bool,), False, True, False) _guard_scalar('Stats.width', self.width, (str,), False, True, False) _guard_scalar('Stats.visible', self.visible, (bool,), False, True, False) + _guard_scalar('Stats.name', self.name, (str,), False, True, False) return _dump( items=[__e.dump() for __e in self.items], justify=self.justify, inset=self.inset, width=self.width, visible=self.visible, + name=self.name, ) @staticmethod @@ -5967,17 +5983,21 @@ def load(__d: Dict) -> 'Stats': _guard_scalar('Stats.width', __d_width, (str,), False, True, False) __d_visible: Any = __d.get('visible') _guard_scalar('Stats.visible', __d_visible, (bool,), False, True, False) + __d_name: Any = __d.get('name') + _guard_scalar('Stats.name', __d_name, (str,), False, True, False) items: List[Stat] = [Stat.load(__e) for __e in __d_items] justify: Optional[str] = __d_justify inset: Optional[bool] = __d_inset width: Optional[str] = __d_width visible: Optional[bool] = __d_visible + name: Optional[str] = __d_name return Stats( items, justify, inset, width, visible, + name, ) @@ -12713,15 +12733,19 @@ def __init__( self, box: str, items: List[Stat], + name: Optional[str] = None, commands: Optional[List[Command]] = None, ): _guard_scalar('TallStatsCard.box', box, (str,), False, False, False) _guard_vector('TallStatsCard.items', items, (Stat,), False, False, False) + _guard_scalar('TallStatsCard.name', name, (str,), False, True, False) _guard_vector('TallStatsCard.commands', commands, (Command,), False, True, False) self.box = box """A string indicating how to place this component on the page.""" self.items = items """The individual stats to be displayed.""" + self.name = name + """An identifying name for this component.""" self.commands = commands """Contextual menu commands for this component.""" @@ -12729,11 +12753,13 @@ def dump(self) -> Dict: """Returns the contents of this object as a dict.""" _guard_scalar('TallStatsCard.box', self.box, (str,), False, False, False) _guard_vector('TallStatsCard.items', self.items, (Stat,), False, False, False) + _guard_scalar('TallStatsCard.name', self.name, (str,), False, True, False) _guard_vector('TallStatsCard.commands', self.commands, (Command,), False, True, False) return _dump( view='tall_stats', box=self.box, items=[__e.dump() for __e in self.items], + name=self.name, commands=None if self.commands is None else [__e.dump() for __e in self.commands], ) @@ -12744,14 +12770,18 @@ def load(__d: Dict) -> 'TallStatsCard': _guard_scalar('TallStatsCard.box', __d_box, (str,), False, False, False) __d_items: Any = __d.get('items') _guard_vector('TallStatsCard.items', __d_items, (dict,), False, False, False) + __d_name: Any = __d.get('name') + _guard_scalar('TallStatsCard.name', __d_name, (str,), False, True, False) __d_commands: Any = __d.get('commands') _guard_vector('TallStatsCard.commands', __d_commands, (dict,), False, True, False) box: str = __d_box items: List[Stat] = [Stat.load(__e) for __e in __d_items] + name: Optional[str] = __d_name commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands] return TallStatsCard( box, items, + name, commands, ) diff --git a/py/h2o_wave/h2o_wave/ui.py b/py/h2o_wave/h2o_wave/ui.py index 13c88404c2..9967255f1d 100644 --- a/py/h2o_wave/h2o_wave/ui.py +++ b/py/h2o_wave/h2o_wave/ui.py @@ -2159,6 +2159,7 @@ def stat( caption: Optional[str] = None, icon: Optional[str] = None, icon_color: Optional[str] = None, + name: Optional[str] = None, ) -> Stat: """Create a stat (a label-value pair) for displaying a metric. @@ -2168,6 +2169,7 @@ def stat( caption: The caption displayed below the primary value. icon: An optional icon, displayed next to the label. icon_color: The color of the icon. + name: An identifying name for this item. Returns: A `h2o_wave.types.Stat` instance. """ @@ -2177,6 +2179,7 @@ def stat( caption, icon, icon_color, + name, ) @@ -2186,6 +2189,7 @@ def stats( inset: Optional[bool] = None, width: Optional[str] = None, visible: Optional[bool] = None, + name: Optional[str] = None, ) -> Component: """Create a set of stats laid out horizontally. @@ -2195,6 +2199,7 @@ def stats( inset: Whether to display the stats with a contrasting background. width: The width of the stats, e.g. '100px'. visible: True if the component should be visible. Defaults to True. + name: An identifying name for this component. Returns: A `h2o_wave.types.Stats` instance. """ @@ -2204,6 +2209,7 @@ def stats( inset, width, visible, + name, )) @@ -4507,6 +4513,7 @@ def tall_series_stat_card( def tall_stats_card( box: str, items: List[Stat], + name: Optional[str] = None, commands: Optional[List[Command]] = None, ) -> TallStatsCard: """Create a vertical label-value pairs collection. Icon in `ui.stat` is not yet supported in this card. @@ -4514,6 +4521,7 @@ def tall_stats_card( Args: box: A string indicating how to place this component on the page. items: The individual stats to be displayed. + name: An identifying name for this component. commands: Contextual menu commands for this component. Returns: A `h2o_wave.types.TallStatsCard` instance. @@ -4521,6 +4529,7 @@ def tall_stats_card( return TallStatsCard( box, items, + name, commands, ) diff --git a/r/R/ui.R b/r/R/ui.R index a5f9a1e518..4f603b4053 100644 --- a/r/R/ui.R +++ b/r/R/ui.R @@ -2540,6 +2540,7 @@ ui_vega_visualization <- function( #' @param caption The caption displayed below the primary value. #' @param icon An optional icon, displayed next to the label. #' @param icon_color The color of the icon. +#' @param name An identifying name for this item. #' @return A Stat instance. #' @export ui_stat <- function( @@ -2547,18 +2548,21 @@ ui_stat <- function( value = NULL, caption = NULL, icon = NULL, - icon_color = NULL) { + icon_color = NULL, + name = NULL) { .guard_scalar("label", "character", label) .guard_scalar("value", "character", value) .guard_scalar("caption", "character", caption) .guard_scalar("icon", "character", icon) .guard_scalar("icon_color", "character", icon_color) + .guard_scalar("name", "character", name) .o <- list( label=label, value=value, caption=caption, icon=icon, - icon_color=icon_color) + icon_color=icon_color, + name=name) class(.o) <- append(class(.o), c(.wave_obj, "WaveStat")) return(.o) } @@ -2571,6 +2575,7 @@ ui_stat <- function( #' @param inset Whether to display the stats with a contrasting background. #' @param width The width of the stats, e.g. '100px'. #' @param visible True if the component should be visible. Defaults to True. +#' @param name An identifying name for this component. #' @return A Stats instance. #' @export ui_stats <- function( @@ -2578,18 +2583,21 @@ ui_stats <- function( justify = NULL, inset = NULL, width = NULL, - visible = NULL) { + visible = NULL, + name = NULL) { .guard_vector("items", "WaveStat", items) # TODO Validate justify .guard_scalar("inset", "logical", inset) .guard_scalar("width", "character", width) .guard_scalar("visible", "logical", visible) + .guard_scalar("name", "character", name) .o <- list(stats=list( items=items, justify=justify, inset=inset, width=width, - visible=visible)) + visible=visible, + name=name)) class(.o) <- append(class(.o), c(.wave_obj, "WaveComponent")) return(.o) } @@ -5278,19 +5286,23 @@ ui_tall_series_stat_card <- function( #' #' @param box A string indicating how to place this component on the page. #' @param items The individual stats to be displayed. +#' @param name An identifying name for this component. #' @param commands Contextual menu commands for this component. #' @return A TallStatsCard instance. #' @export ui_tall_stats_card <- function( box, items, + name = NULL, commands = NULL) { .guard_scalar("box", "character", box) .guard_vector("items", "WaveStat", items) + .guard_scalar("name", "character", name) .guard_vector("commands", "WaveCommand", commands) .o <- list( box=box, items=items, + name=name, commands=commands, view='tall_stats') class(.o) <- append(class(.o), c(.wave_obj, "WaveTallStatsCard")) diff --git a/tools/intellij-plugin/src/main/resources/templates/wave-components.xml b/tools/intellij-plugin/src/main/resources/templates/wave-components.xml index cbd7a92848..ae064bd8ab 100644 --- a/tools/intellij-plugin/src/main/resources/templates/wave-components.xml +++ b/tools/intellij-plugin/src/main/resources/templates/wave-components.xml @@ -2281,22 +2281,24 @@