Added columns values in suggestion + fixed commands key conflicts bug
This commit is contained in:
@@ -59,15 +59,42 @@ class DataGridsRegistry(SingleInstance):
|
||||
try:
|
||||
as_fullname_dict = self._get_entries_as_full_name_dict()
|
||||
grid_id = as_fullname_dict[table_name]
|
||||
|
||||
|
||||
# load dataframe
|
||||
state_id = f"{grid_id}#state"
|
||||
state = self._db_manager.load(state_id)
|
||||
df = state["ne_df"] if state else None
|
||||
return len(df) if df is not None else 0
|
||||
|
||||
|
||||
except KeyError:
|
||||
return 0
|
||||
|
||||
def get_column_type(self, table_name, column_name):
|
||||
"""
|
||||
Get the type of a column.
|
||||
|
||||
Args:
|
||||
table_name: The DataGrid name
|
||||
column_name: The column name
|
||||
|
||||
Returns:
|
||||
ColumnType enum value or None if not found
|
||||
"""
|
||||
try:
|
||||
as_fullname_dict = self._get_entries_as_full_name_dict()
|
||||
grid_id = as_fullname_dict[table_name]
|
||||
|
||||
# load datagrid state
|
||||
state_id = f"{grid_id}#state"
|
||||
state = self._db_manager.load(state_id)
|
||||
|
||||
if state and "columns" in state:
|
||||
for col in state["columns"]:
|
||||
if col.col_id == column_name:
|
||||
return col.type
|
||||
return None
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def _get_all_entries(self):
|
||||
return {k: v for k, v in self._db_manager.load(DATAGRIDS_REGISTRY_ENTRY_KEY).items()
|
||||
|
||||
@@ -48,10 +48,13 @@ class Command:
|
||||
# either there is no parameter (so one single instance of the command is enough)
|
||||
# or the parameter is a kwargs (so the parameters are provided when the command is called)
|
||||
if key is None:
|
||||
if owner is not None and args is None: # args is not provided
|
||||
key = f"{owner.get_full_id()}-{name}"
|
||||
else:
|
||||
key = f"{name}-{_compute_from_args()}"
|
||||
key_parts = []
|
||||
if owner is not None:
|
||||
key_parts.append(f"{owner.get_full_id()}")
|
||||
key_parts.append(name)
|
||||
if args:
|
||||
key_parts.append(_compute_from_args())
|
||||
key = "-".join(key_parts)
|
||||
else:
|
||||
key = key.replace("#{args}", _compute_from_args())
|
||||
if owner is not None:
|
||||
@@ -122,6 +125,8 @@ class Command:
|
||||
|
||||
def execute(self, client_response: dict = None):
|
||||
logger.debug(f"Executing command {self.name} with arguments {client_response=}")
|
||||
if self._htmx_extra.get("hx-target", "").startswith("#tsm_"):
|
||||
logger.warning(f" Command {self.name} needs a selection manager to work properly.")
|
||||
with ObservableResultCollector(self._bindings) as collector:
|
||||
kwargs = self._create_kwargs(self.default_kwargs,
|
||||
client_response,
|
||||
@@ -145,6 +150,10 @@ class Command:
|
||||
and r.get("id", None) is not None):
|
||||
r.attrs["hx-swap-oob"] = r.attrs.get("hx-swap-oob", "true")
|
||||
|
||||
if self._htmx_extra.get("hx-target", "").startswith("#tsm_"):
|
||||
ret_debug = [f"<{r.tag} id={r.attrs.get('id', '')}/>" if r else "None" for r in all_ret]
|
||||
logger.warning(f" {ret_debug=}")
|
||||
|
||||
return all_ret[0] if len(all_ret) == 1 else all_ret
|
||||
|
||||
def htmx(self, target: Optional[str] = "this", swap="outerHTML", trigger=None, auto_swap_oob=True):
|
||||
|
||||
@@ -79,11 +79,10 @@ class DbObject:
|
||||
return # still under initialization
|
||||
|
||||
if self._reload_self():
|
||||
logger.debug(f"finalize_initialization ({self._name}) : Loaded existing content.")
|
||||
# logger.debug(f"finalize_initialization ({self._name}) : Loaded existing content.")
|
||||
return
|
||||
else:
|
||||
logger.debug(
|
||||
f"finalize_initialization ({self._name}) : No existing content found, creating new entry {self._save_state=}.")
|
||||
# logger.debug(f"finalize_initialization ({self._name}) : No existing content found, creating new entry {self._save_state=}.")
|
||||
self._save_self()
|
||||
|
||||
def _reload_self(self):
|
||||
|
||||
@@ -181,8 +181,8 @@ class FormattingCompletionEngine(BaseCompletionEngine):
|
||||
return presets.COMPARISON_OPERATORS
|
||||
|
||||
case Context.OPERATOR_VALUE | Context.BETWEEN_VALUE:
|
||||
# col., True, False + column values
|
||||
base = presets.OPERATOR_VALUE_BASE.copy()
|
||||
# Filter base suggestions according to column type
|
||||
base = self._get_base_suggestions_for_column_type(scope)
|
||||
base.extend(self._get_column_value_suggestions(scope))
|
||||
return base
|
||||
|
||||
@@ -363,6 +363,44 @@ class FormattingCompletionEngine(BaseCompletionEngine):
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
def _get_base_suggestions_for_column_type(self, scope: DetectedScope) -> list[Suggestion]:
|
||||
"""
|
||||
Filter base suggestions according to column type.
|
||||
|
||||
Only suggests True/False for Boolean columns.
|
||||
Always suggests col. for cross-column comparisons.
|
||||
|
||||
Args:
|
||||
scope: The detected scope containing column information
|
||||
|
||||
Returns:
|
||||
List of filtered base suggestions
|
||||
"""
|
||||
from myfasthtml.core.constants import ColumnType
|
||||
|
||||
if not scope.column_name:
|
||||
# No column context, return all base suggestions
|
||||
return presets.OPERATOR_VALUE_BASE.copy()
|
||||
|
||||
try:
|
||||
table_name = scope.table_name or self.table_name or ""
|
||||
col_type = self.provider.get_column_type(table_name, scope.column_name)
|
||||
|
||||
suggestions = []
|
||||
|
||||
# Always suggest col. for cross-column comparisons
|
||||
suggestions.append(Suggestion("col.", "Reference another column", "keyword"))
|
||||
|
||||
# Add True/False only for Boolean columns
|
||||
if col_type == ColumnType.Bool:
|
||||
suggestions.append(Suggestion("True", "Boolean true", "literal"))
|
||||
suggestions.append(Suggestion("False", "Boolean false", "literal"))
|
||||
|
||||
return suggestions
|
||||
except Exception:
|
||||
# Fallback to default if type detection fails
|
||||
return presets.OPERATOR_VALUE_BASE.copy()
|
||||
|
||||
|
||||
def get_completions(
|
||||
text: str,
|
||||
|
||||
@@ -72,3 +72,18 @@ class DatagridMetadataProvider(BaseMetadataProvider):
|
||||
Number of rows
|
||||
"""
|
||||
...
|
||||
|
||||
def get_column_type(self, table_name: str, column_name: str):
|
||||
"""
|
||||
Return the type of a column.
|
||||
|
||||
Used to filter suggestions based on column type.
|
||||
|
||||
Args:
|
||||
table_name: The DataGrid name
|
||||
column_name: The column name
|
||||
|
||||
Returns:
|
||||
ColumnType enum value or None if not found
|
||||
"""
|
||||
...
|
||||
|
||||
@@ -6,6 +6,8 @@ from myfasthtml.controls.helpers import Ids
|
||||
from myfasthtml.core.constants import NO_DEFAULT_VALUE
|
||||
from myfasthtml.core.utils import pascal_to_snake, get_class, snake_to_pascal
|
||||
|
||||
VERBOSE_VERBOSE = False
|
||||
|
||||
logger = logging.getLogger("InstancesManager")
|
||||
|
||||
special_session = {
|
||||
@@ -26,12 +28,19 @@ class BaseInstance:
|
||||
def __new__(cls, *args, **kwargs):
|
||||
# Extract arguments from both positional and keyword arguments
|
||||
# Signature matches __init__: parent, session=None, _id=None, auto_register=True
|
||||
if VERBOSE_VERBOSE:
|
||||
logger.debug(f"Creating new instance of type {cls.__name__}")
|
||||
|
||||
parent = args[0] if len(args) > 0 and isinstance(args[0], BaseInstance) else kwargs.get("parent", None)
|
||||
session = args[1] if len(args) > 1 and isinstance(args[1], dict) else kwargs.get("session", None)
|
||||
_id = args[2] if len(args) > 2 and isinstance(args[2], str) else kwargs.get("_id", None)
|
||||
if VERBOSE_VERBOSE:
|
||||
logger.debug(f" parent={parent}, session={session}, _id={_id}")
|
||||
|
||||
# Compute _id
|
||||
_id = cls.compute_id(_id, parent)
|
||||
if VERBOSE_VERBOSE:
|
||||
logger.debug(f" computed id={_id}")
|
||||
|
||||
if session is None:
|
||||
if parent is not None:
|
||||
@@ -46,9 +55,14 @@ class BaseInstance:
|
||||
res = InstancesManager.instances[key]
|
||||
if type(res) is not cls:
|
||||
raise TypeError(f"Instance with id {_id} already exists, but is of type {type(res)}")
|
||||
|
||||
if VERBOSE_VERBOSE:
|
||||
logger.debug(f" instance {_id} already exists, returning existing instance")
|
||||
return res
|
||||
|
||||
# Otherwise create a new instance
|
||||
if VERBOSE_VERBOSE:
|
||||
logger.debug(f" creating new instance")
|
||||
instance = super().__new__(cls)
|
||||
instance._is_new_instance = True # mark as fresh
|
||||
return instance
|
||||
|
||||
Reference in New Issue
Block a user