updated panel display
This commit is contained in:
@@ -51,6 +51,12 @@ def global_config() -> List[Dict[str, Any]]:
|
||||
"label": "Auto-Update",
|
||||
"default": "true",
|
||||
"choices": ["true", "false"]
|
||||
},
|
||||
{
|
||||
"key": "table_appearance",
|
||||
"label": "Table Appearance",
|
||||
"default": "rainbow",
|
||||
"choices": ["plain", "bw-striped", "rainbow"]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
+116
-26
@@ -5,7 +5,7 @@ import inspect
|
||||
import logging
|
||||
import threading
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from typing import Any, Optional, Sequence
|
||||
|
||||
from SYS.rich_display import console_for
|
||||
|
||||
@@ -43,6 +43,106 @@ def is_debug_enabled() -> bool:
|
||||
return _DEBUG_ENABLED
|
||||
|
||||
|
||||
def _debug_output_suppressed() -> bool:
|
||||
try:
|
||||
stderr_name = getattr(sys.stderr, "name", "")
|
||||
return "nul" in str(stderr_name).lower() or "/dev/null" in str(stderr_name)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def _debug_output_file(file=None):
|
||||
stream = get_thread_stream()
|
||||
if stream is not None:
|
||||
return stream
|
||||
if file is not None:
|
||||
return file
|
||||
return sys.stderr
|
||||
|
||||
|
||||
def _is_rich_renderable(value: Any) -> bool:
|
||||
if value is None:
|
||||
return False
|
||||
if isinstance(value, (str, bytes, bytearray)):
|
||||
return False
|
||||
return bool(
|
||||
hasattr(value, "__rich_console__")
|
||||
or hasattr(value, "__rich__")
|
||||
or value.__class__.__module__.startswith("rich.")
|
||||
)
|
||||
|
||||
|
||||
def _caller_location(depth: int = 1) -> tuple[str, str]:
|
||||
frame = inspect.currentframe()
|
||||
current = frame
|
||||
try:
|
||||
for _ in range(max(0, int(depth))):
|
||||
if current is None:
|
||||
break
|
||||
current = current.f_back
|
||||
|
||||
if current is None:
|
||||
return "", ""
|
||||
|
||||
return Path(current.f_code.co_filename).stem, current.f_code.co_name
|
||||
finally:
|
||||
del frame
|
||||
|
||||
|
||||
def _debug_db_log(*, caller_name: str, message: str, level: str = "DEBUG") -> None:
|
||||
if not _DB_LOGGER:
|
||||
return
|
||||
try:
|
||||
_DB_LOGGER(level, caller_name, message)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def debug_panel(
|
||||
title: str,
|
||||
rows: Sequence[tuple[str, Any]],
|
||||
*,
|
||||
file=None,
|
||||
border_style: str = "cyan",
|
||||
) -> None:
|
||||
"""Render a compact key/value debug panel when debug logging is enabled."""
|
||||
if not _DEBUG_ENABLED or _debug_output_suppressed():
|
||||
return
|
||||
|
||||
target_file = _debug_output_file(file)
|
||||
try:
|
||||
from rich.panel import Panel
|
||||
from rich.table import Table as RichTable
|
||||
|
||||
grid = RichTable.grid(padding=(0, 1))
|
||||
grid.add_column("Key", style="cyan", no_wrap=True)
|
||||
grid.add_column("Value")
|
||||
for key, val in rows:
|
||||
try:
|
||||
grid.add_row(str(key), str(val))
|
||||
except Exception:
|
||||
grid.add_row(str(key), "<unprintable>")
|
||||
|
||||
debug(
|
||||
Panel(
|
||||
grid,
|
||||
title=str(title or "Debug"),
|
||||
expand=False,
|
||||
border_style=border_style,
|
||||
),
|
||||
file=target_file,
|
||||
)
|
||||
|
||||
file_name, func_name = _caller_location(depth=2)
|
||||
caller_name = f"{file_name}.{func_name}" if file_name and func_name else ""
|
||||
_debug_db_log(
|
||||
caller_name=caller_name,
|
||||
message=f"[{title}] " + "; ".join(f"{k}={v}" for k, v in rows),
|
||||
)
|
||||
except Exception:
|
||||
debug(title, list(rows), file=target_file)
|
||||
|
||||
|
||||
def debug(*args, **kwargs) -> None:
|
||||
"""Print debug message if debug logging is enabled.
|
||||
|
||||
@@ -53,26 +153,24 @@ def debug(*args, **kwargs) -> None:
|
||||
|
||||
# Check if stderr has been redirected to /dev/null (quiet mode)
|
||||
# If so, skip output to avoid queuing in background worker's capture
|
||||
try:
|
||||
stderr_name = getattr(sys.stderr, "name", "")
|
||||
if "nul" in str(stderr_name).lower() or "/dev/null" in str(stderr_name):
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
if _debug_output_suppressed():
|
||||
return
|
||||
|
||||
# Check for thread-local stream first
|
||||
stream = get_thread_stream()
|
||||
if stream:
|
||||
kwargs["file"] = stream
|
||||
# Set default to stderr for debug messages
|
||||
elif "file" not in kwargs:
|
||||
kwargs["file"] = sys.stderr
|
||||
target_file = _debug_output_file(kwargs.pop("file", None))
|
||||
|
||||
if len(args) == 1 and _is_rich_renderable(args[0]):
|
||||
renderable = args[0]
|
||||
console_for(target_file).print(renderable)
|
||||
file_name, func_name = _caller_location(depth=1)
|
||||
caller_name = f"{file_name}.{func_name}" if file_name and func_name else ""
|
||||
_debug_db_log(caller_name=caller_name, message=f"<rich:{type(renderable).__name__}>")
|
||||
return
|
||||
|
||||
# Prepend DEBUG label
|
||||
args = ("DEBUG:", *args)
|
||||
|
||||
# Use the same logic as log()
|
||||
log(*args, **kwargs)
|
||||
log(*args, file=target_file, **kwargs)
|
||||
|
||||
|
||||
def debug_inspect(
|
||||
@@ -97,19 +195,11 @@ def debug_inspect(
|
||||
return
|
||||
|
||||
# Mirror debug() quiet-mode guard.
|
||||
try:
|
||||
stderr_name = getattr(sys.stderr, "name", "")
|
||||
if "nul" in str(stderr_name).lower() or "/dev/null" in str(stderr_name):
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
if _debug_output_suppressed():
|
||||
return
|
||||
|
||||
# Resolve destination stream.
|
||||
stream = get_thread_stream()
|
||||
if stream is not None:
|
||||
file = stream
|
||||
elif file is None:
|
||||
file = sys.stderr
|
||||
file = _debug_output_file(file)
|
||||
|
||||
# Compute caller prefix (same as log()).
|
||||
prefix = None
|
||||
|
||||
+76
-17
@@ -10,7 +10,7 @@ from dataclasses import dataclass, field
|
||||
from contextvars import ContextVar
|
||||
from typing import Any, Dict, List, Optional, Sequence, Callable
|
||||
from SYS.models import PipelineStageContext
|
||||
from SYS.logger import log, debug, is_debug_enabled
|
||||
from SYS.logger import log, debug, debug_panel, is_debug_enabled
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
from SYS.worker import WorkerManagerRegistry, WorkerStages
|
||||
@@ -28,6 +28,47 @@ HELP_EXAMPLE_SOURCE_COMMANDS = {
|
||||
}
|
||||
|
||||
|
||||
def _emit_selection_debug_panel(
|
||||
*,
|
||||
selection_token: Any,
|
||||
selection_indices: Sequence[int],
|
||||
item_count: int,
|
||||
filtered_count: int,
|
||||
stage_table_present: bool,
|
||||
display_table_present: bool,
|
||||
stage_is_last: bool,
|
||||
row_action: Optional[Sequence[Any]] = None,
|
||||
downstream_stages: Optional[Sequence[Sequence[Any]]] = None,
|
||||
mode: Optional[str] = None,
|
||||
) -> None:
|
||||
if not is_debug_enabled():
|
||||
return
|
||||
|
||||
try:
|
||||
rows: List[tuple[str, Any]] = [
|
||||
("selection", str(selection_token or "")),
|
||||
("indices", [int(idx) + 1 for idx in (selection_indices or [])]),
|
||||
("items", int(item_count)),
|
||||
("filtered", int(filtered_count)),
|
||||
("stage_table", bool(stage_table_present)),
|
||||
("display_table", bool(display_table_present)),
|
||||
("stage_is_last", bool(stage_is_last)),
|
||||
("downstream_stages", len(list(downstream_stages or []))),
|
||||
]
|
||||
if mode:
|
||||
rows.insert(1, ("mode", str(mode)))
|
||||
if row_action:
|
||||
rows.append(("row_action", " ".join(str(part) for part in row_action if part is not None)))
|
||||
|
||||
debug_panel(
|
||||
f"Selection replay {selection_token}",
|
||||
rows,
|
||||
border_style="magenta",
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def set_live_progress(progress_ui: Any) -> None:
|
||||
"""Register the current Live progress UI so cmdlets can suspend it during prompts."""
|
||||
state = _get_pipeline_state()
|
||||
@@ -1883,6 +1924,7 @@ class PipelineExecutor:
|
||||
selected_row_args: List[str] = []
|
||||
skip_pipe_expansion = source_cmd in {".pipe", ".mpv"} and len(stages) > 0
|
||||
prefer_row_action = False
|
||||
preferred_row_action = None
|
||||
if len(selection_indices) == 1 and not stages:
|
||||
try:
|
||||
row_action = _get_row_action(selection_indices[0])
|
||||
@@ -1890,10 +1932,7 @@ class PipelineExecutor:
|
||||
row_action = None
|
||||
if row_action:
|
||||
prefer_row_action = True
|
||||
debug(
|
||||
"@N: skipping source command expansion because row has explicit selection_action "
|
||||
f"{row_action}"
|
||||
)
|
||||
preferred_row_action = list(row_action)
|
||||
# Command expansion via @N:
|
||||
# - Default behavior: expand ONLY for single-row selections.
|
||||
# - Special case: allow multi-row expansion for add-file directory tables by
|
||||
@@ -1978,7 +2017,7 @@ class PipelineExecutor:
|
||||
except Exception:
|
||||
logger.exception("Failed to record pipeline log step for @N expansion (pipeline_session=%r)", getattr(pipeline_session, 'worker_id', None))
|
||||
elif selected_row_args and stages:
|
||||
debug("@N: skipping source command expansion because downstream stages exist")
|
||||
pass
|
||||
|
||||
stage_table = None
|
||||
try:
|
||||
@@ -2003,8 +2042,6 @@ class PipelineExecutor:
|
||||
except Exception:
|
||||
stage_table = None
|
||||
|
||||
debug(f"@N: stage_table={stage_table is not None}, display_table={display_table is not None}")
|
||||
|
||||
# ====================================================================
|
||||
# PHASE 4: Retrieve and filter items from current result set
|
||||
# ====================================================================
|
||||
@@ -2015,14 +2052,31 @@ class PipelineExecutor:
|
||||
except Exception as exc:
|
||||
debug(f"@N: Exception getting items_list: {exc}")
|
||||
items_list = []
|
||||
|
||||
debug(f"@N: selection_indices={selection_indices}, items_list length={len(items_list)}")
|
||||
resolved_items = items_list if items_list else []
|
||||
if items_list:
|
||||
filtered = [
|
||||
resolved_items[i] for i in selection_indices
|
||||
if 0 <= i < len(resolved_items)
|
||||
]
|
||||
if selection_indices:
|
||||
if len(selection_indices) == 1:
|
||||
selection_label = f"@{selection_indices[0] + 1}"
|
||||
else:
|
||||
selection_label = "@{" + ",".join(str(idx + 1) for idx in selection_indices) + "}"
|
||||
else:
|
||||
selection_label = "@selection"
|
||||
_emit_selection_debug_panel(
|
||||
selection_token=selection_label,
|
||||
selection_indices=selection_indices,
|
||||
item_count=len(items_list),
|
||||
filtered_count=len(filtered),
|
||||
stage_table_present=(stage_table is not None),
|
||||
display_table_present=(display_table is not None),
|
||||
stage_is_last=(not stages),
|
||||
row_action=preferred_row_action,
|
||||
downstream_stages=stages,
|
||||
mode=("row_action" if preferred_row_action else "selection"),
|
||||
)
|
||||
if not filtered:
|
||||
print("No items matched selection in pipeline\n")
|
||||
return False, None
|
||||
@@ -2088,15 +2142,12 @@ class PipelineExecutor:
|
||||
filtered = track_items
|
||||
table_type_hint = "tidal.track"
|
||||
|
||||
debug(f"@N: calling _maybe_run_class_selector with filtered={len(filtered)} items, stage_is_last={not stages}")
|
||||
if PipelineExecutor._maybe_run_class_selector(
|
||||
ctx,
|
||||
config,
|
||||
filtered,
|
||||
stage_is_last=(not stages)):
|
||||
debug(f"@N: _maybe_run_class_selector returned True, returning False")
|
||||
return False, None
|
||||
debug(f"@N: _maybe_run_class_selector returned False, continuing")
|
||||
|
||||
from SYS.pipe_object import coerce_to_pipe_object
|
||||
|
||||
@@ -2105,7 +2156,6 @@ class PipelineExecutor:
|
||||
filtered_pipe_objs
|
||||
if len(filtered_pipe_objs) > 1 else filtered_pipe_objs[0]
|
||||
)
|
||||
debug(f"@N: coerced piped_result, stages={stages}")
|
||||
|
||||
if pipeline_session and worker_manager:
|
||||
try:
|
||||
@@ -2204,7 +2254,6 @@ class PipelineExecutor:
|
||||
print("Auto-applying metadata selection via get-tag")
|
||||
stages.append(["get-tag"])
|
||||
elif auto_stage:
|
||||
debug(f"@N: Found auto_stage={auto_stage}, appending")
|
||||
try:
|
||||
print(f"Auto-running selection via {auto_stage[0]}")
|
||||
except Exception:
|
||||
@@ -2238,7 +2287,6 @@ class PipelineExecutor:
|
||||
if not stages and selection_indices and len(selection_indices) == 1:
|
||||
row_action = _get_row_action(selection_indices[0], items_list)
|
||||
if row_action:
|
||||
debug(f"@N: applying row_action {row_action}")
|
||||
stages.append(row_action)
|
||||
if pipeline_session and worker_manager:
|
||||
try:
|
||||
@@ -2464,7 +2512,18 @@ class PipelineExecutor:
|
||||
ctx = sys.modules[__name__]
|
||||
|
||||
try:
|
||||
debug(f"execute_tokens: tokens={tokens}")
|
||||
try:
|
||||
from SYS.logger import debug_panel
|
||||
|
||||
debug_panel(
|
||||
"Pipeline execution",
|
||||
[
|
||||
("command", " ".join(str(tok) for tok in tokens)),
|
||||
("token_count", len(tokens)),
|
||||
],
|
||||
)
|
||||
except Exception:
|
||||
debug(f"execute_tokens: tokens={tokens}")
|
||||
self._try_clear_pipeline_stop(ctx)
|
||||
|
||||
# REPL guard: stage-local tables should not persist across independent
|
||||
|
||||
+116
-19
@@ -16,6 +16,7 @@ from dataclasses import dataclass, field
|
||||
from typing import Any, Dict, List, Optional, Callable, Set
|
||||
from pathlib import Path
|
||||
import json
|
||||
import re
|
||||
|
||||
from rich.box import SIMPLE
|
||||
from rich.console import Group
|
||||
@@ -113,14 +114,97 @@ _RESULT_TABLE_ROW_STYLE_LOOP: List[tuple[str, str]] = [
|
||||
("#ffffff", "#000000"),
|
||||
]
|
||||
|
||||
_RESULT_TABLE_BW_ROW_STYLE_LOOP: List[tuple[str, str]] = [
|
||||
("#000000", "#ffffff"),
|
||||
("#ffffff", "#000000"),
|
||||
]
|
||||
|
||||
RESULT_TABLE_HEADER_STYLE = "bold #000000 on #ffffff"
|
||||
RESULT_TABLE_BORDER_STYLE = "#000000 on #ffffff"
|
||||
RESULT_TABLE_PLAIN_HEADER_STYLE = "bold"
|
||||
|
||||
_RESULT_TABLE_APPEARANCE_ALIASES: Dict[str, str] = {
|
||||
"": "rainbow",
|
||||
"rainbow": "rainbow",
|
||||
"default": "rainbow",
|
||||
"plain": "plain",
|
||||
"none": "plain",
|
||||
"bw": "bw-striped",
|
||||
"b-w": "bw-striped",
|
||||
"b-w-striped": "bw-striped",
|
||||
"bw-striped": "bw-striped",
|
||||
"b-w-stripes": "bw-striped",
|
||||
"bw-stripes": "bw-striped",
|
||||
"black-white": "bw-striped",
|
||||
"black-white-striped": "bw-striped",
|
||||
"black-white-stripes": "bw-striped",
|
||||
"black-and-white": "bw-striped",
|
||||
"black-and-white-striped": "bw-striped",
|
||||
"black-and-white-stripes": "bw-striped",
|
||||
}
|
||||
|
||||
|
||||
def get_result_table_row_style(row_index: int) -> str:
|
||||
text_color, bg_color = _RESULT_TABLE_ROW_STYLE_LOOP[
|
||||
row_index % len(_RESULT_TABLE_ROW_STYLE_LOOP)
|
||||
]
|
||||
def normalize_result_table_appearance_mode(value: Any) -> str:
|
||||
text = str(value or "").strip().lower()
|
||||
if not text:
|
||||
return "rainbow"
|
||||
|
||||
collapsed = re.sub(r"[^a-z0-9]+", "-", text).strip("-")
|
||||
return _RESULT_TABLE_APPEARANCE_ALIASES.get(collapsed, "rainbow")
|
||||
|
||||
|
||||
def get_result_table_appearance_mode(config: Optional[Dict[str, Any]] = None) -> str:
|
||||
cfg = config
|
||||
if cfg is None:
|
||||
try:
|
||||
from SYS.config import load_config
|
||||
|
||||
cfg = load_config() or {}
|
||||
except Exception:
|
||||
cfg = {}
|
||||
|
||||
raw_value = None
|
||||
if isinstance(cfg, dict):
|
||||
raw_value = cfg.get("table_appearance")
|
||||
|
||||
return normalize_result_table_appearance_mode(raw_value)
|
||||
|
||||
|
||||
def get_result_table_header_style(config: Optional[Dict[str, Any]] = None) -> str:
|
||||
mode = get_result_table_appearance_mode(config)
|
||||
if mode == "plain":
|
||||
return RESULT_TABLE_PLAIN_HEADER_STYLE
|
||||
return RESULT_TABLE_HEADER_STYLE
|
||||
|
||||
|
||||
def get_result_table_border_style(config: Optional[Dict[str, Any]] = None) -> str:
|
||||
mode = get_result_table_appearance_mode(config)
|
||||
if mode == "plain":
|
||||
return ""
|
||||
return RESULT_TABLE_BORDER_STYLE
|
||||
|
||||
|
||||
def get_result_table_panel_style(config: Optional[Dict[str, Any]] = None) -> str:
|
||||
mode = get_result_table_appearance_mode(config)
|
||||
if mode == "plain":
|
||||
return ""
|
||||
return "on #ffffff"
|
||||
|
||||
|
||||
def get_result_table_row_style(
|
||||
row_index: int,
|
||||
appearance_mode: Optional[str] = None,
|
||||
config: Optional[Dict[str, Any]] = None,
|
||||
) -> str:
|
||||
mode = appearance_mode or get_result_table_appearance_mode(config)
|
||||
if mode == "plain":
|
||||
return ""
|
||||
|
||||
style_loop = (
|
||||
_RESULT_TABLE_BW_ROW_STYLE_LOOP
|
||||
if mode == "bw-striped" else _RESULT_TABLE_ROW_STYLE_LOOP
|
||||
)
|
||||
text_color, bg_color = style_loop[row_index % len(style_loop)]
|
||||
return f"{text_color} on {bg_color}"
|
||||
|
||||
|
||||
@@ -1435,16 +1519,21 @@ class Table:
|
||||
|
||||
def to_rich(self):
|
||||
"""Return a Rich renderable representing this table."""
|
||||
appearance_mode = get_result_table_appearance_mode()
|
||||
header_style = get_result_table_header_style({"table_appearance": appearance_mode})
|
||||
border_style = get_result_table_border_style({"table_appearance": appearance_mode})
|
||||
panel_style = get_result_table_panel_style({"table_appearance": appearance_mode})
|
||||
|
||||
if not self.rows:
|
||||
empty = Text("No results")
|
||||
return (
|
||||
Panel(
|
||||
empty,
|
||||
title=Text(str(self.title), style=RESULT_TABLE_HEADER_STYLE),
|
||||
border_style=RESULT_TABLE_BORDER_STYLE,
|
||||
title=Text(str(self.title), style=header_style),
|
||||
border_style=border_style,
|
||||
padding=(0, 0),
|
||||
expand=False,
|
||||
style="on #ffffff",
|
||||
style=panel_style,
|
||||
)
|
||||
if self.title
|
||||
else empty
|
||||
@@ -1460,8 +1549,8 @@ class Table:
|
||||
|
||||
table = RichTable(
|
||||
show_header=True,
|
||||
header_style=RESULT_TABLE_HEADER_STYLE,
|
||||
border_style=RESULT_TABLE_BORDER_STYLE,
|
||||
header_style=header_style,
|
||||
border_style=border_style,
|
||||
box=None,
|
||||
expand=False,
|
||||
show_lines=False,
|
||||
@@ -1497,7 +1586,13 @@ class Table:
|
||||
for name in col_names:
|
||||
val = row.get_column(name) or ""
|
||||
cells.append(self._apply_value_case(_sanitize_cell_text(val)))
|
||||
table.add_row(*cells, style=get_result_table_row_style(row_idx - 1))
|
||||
table.add_row(
|
||||
*cells,
|
||||
style=get_result_table_row_style(
|
||||
row_idx - 1,
|
||||
appearance_mode=appearance_mode,
|
||||
),
|
||||
)
|
||||
|
||||
if self.title or self.header_lines:
|
||||
header_bits = [Text(line) for line in (self.header_lines or [])]
|
||||
@@ -1505,11 +1600,11 @@ class Table:
|
||||
return (
|
||||
Panel(
|
||||
renderable,
|
||||
title=Text(str(self.title), style=RESULT_TABLE_HEADER_STYLE),
|
||||
border_style=RESULT_TABLE_BORDER_STYLE,
|
||||
title=Text(str(self.title), style=header_style),
|
||||
border_style=border_style,
|
||||
padding=(0, 0),
|
||||
expand=False,
|
||||
style="on #ffffff",
|
||||
style=panel_style,
|
||||
)
|
||||
if self.title
|
||||
else renderable
|
||||
@@ -2385,11 +2480,13 @@ class ItemDetailView(Table):
|
||||
elements = []
|
||||
|
||||
if has_details:
|
||||
header_style = get_result_table_header_style()
|
||||
border_style = get_result_table_border_style()
|
||||
detail_title = str(self.detail_title or "Item Details").strip() or "Item Details"
|
||||
elements.append(Panel(
|
||||
details_table,
|
||||
title=Text(detail_title, style=RESULT_TABLE_HEADER_STYLE),
|
||||
border_style=RESULT_TABLE_BORDER_STYLE,
|
||||
title=Text(detail_title, style=header_style),
|
||||
border_style=border_style,
|
||||
padding=(1, 2)
|
||||
))
|
||||
|
||||
@@ -2397,11 +2494,11 @@ class ItemDetailView(Table):
|
||||
# If it's a Panel already (from super().to_rich() with title), use it directly
|
||||
# but force the border style to the result-table standard for consistency
|
||||
if isinstance(results_renderable, Panel):
|
||||
results_renderable.border_style = RESULT_TABLE_BORDER_STYLE
|
||||
results_renderable.border_style = get_result_table_border_style()
|
||||
if results_renderable.title:
|
||||
results_renderable.title = Text(
|
||||
str(results_renderable.title),
|
||||
style=RESULT_TABLE_HEADER_STYLE,
|
||||
style=get_result_table_header_style(),
|
||||
)
|
||||
# Add a bit of padding inside if it contains a table
|
||||
elements.append(results_renderable)
|
||||
@@ -2416,8 +2513,8 @@ class ItemDetailView(Table):
|
||||
elements.append(
|
||||
Panel(
|
||||
results_group,
|
||||
title=Text(str(display_title), style=RESULT_TABLE_HEADER_STYLE),
|
||||
border_style=RESULT_TABLE_BORDER_STYLE,
|
||||
title=Text(str(display_title), style=get_result_table_header_style()),
|
||||
border_style=get_result_table_border_style(),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -13,9 +13,10 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from SYS.result_table import (
|
||||
RESULT_TABLE_BORDER_STYLE,
|
||||
RESULT_TABLE_HEADER_STYLE,
|
||||
apply_result_table_layout,
|
||||
get_result_table_appearance_mode,
|
||||
get_result_table_border_style,
|
||||
get_result_table_header_style,
|
||||
get_result_table_row_style,
|
||||
)
|
||||
from SYS.result_table_api import ColumnSpec, ResultModel, ResultTable, Renderer
|
||||
@@ -38,8 +39,8 @@ class RichRenderer(Renderer):
|
||||
|
||||
table = RichTable(
|
||||
show_header=True,
|
||||
header_style=RESULT_TABLE_HEADER_STYLE,
|
||||
border_style=RESULT_TABLE_BORDER_STYLE,
|
||||
header_style=get_result_table_header_style(),
|
||||
border_style=get_result_table_border_style(),
|
||||
box=None,
|
||||
padding=(0, 1),
|
||||
pad_edge=False,
|
||||
@@ -47,6 +48,7 @@ class RichRenderer(Renderer):
|
||||
expand=False,
|
||||
)
|
||||
apply_result_table_layout(table)
|
||||
appearance_mode = get_result_table_appearance_mode()
|
||||
cols = list(columns)
|
||||
for col in cols:
|
||||
if str(col.header or "").strip().lower() == "tag":
|
||||
@@ -71,7 +73,13 @@ class RichRenderer(Renderer):
|
||||
logger.exception("Column extractor failed for '%s': %s", col.header, exc)
|
||||
cell = ""
|
||||
cells.append(cell)
|
||||
table.add_row(*cells, style=get_result_table_row_style(row_idx))
|
||||
table.add_row(
|
||||
*cells,
|
||||
style=get_result_table_row_style(
|
||||
row_idx,
|
||||
appearance_mode=appearance_mode,
|
||||
),
|
||||
)
|
||||
|
||||
return table
|
||||
|
||||
|
||||
Reference in New Issue
Block a user