split out columns
This commit is contained in:
parent
547a65e19f
commit
1bc94bfd0a
89
src/tt/tui/columns.py
Normal file
89
src/tt/tui/columns.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import datetime
|
||||||
|
from ..utils import (
|
||||||
|
get_color_enum,
|
||||||
|
get_colored_date,
|
||||||
|
)
|
||||||
|
from .modals import ChoiceModal, DateModal
|
||||||
|
|
||||||
|
class NotifyValidationError(Exception):
|
||||||
|
"""will notify and continue if raised"""
|
||||||
|
|
||||||
|
|
||||||
|
ELLIPSIS = "…"
|
||||||
|
|
||||||
|
|
||||||
|
class TableColumnConfig:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
field: str,
|
||||||
|
display_name: str,
|
||||||
|
*,
|
||||||
|
default=None,
|
||||||
|
enable_editor=False,
|
||||||
|
filterable=True,
|
||||||
|
read_only=False,
|
||||||
|
):
|
||||||
|
self.field = field
|
||||||
|
self.display_name = display_name
|
||||||
|
self.default = default
|
||||||
|
self.enable_editor = enable_editor
|
||||||
|
self.filterable = filterable
|
||||||
|
self.read_only = read_only
|
||||||
|
|
||||||
|
def preprocess(self, val):
|
||||||
|
return val # no-op
|
||||||
|
|
||||||
|
def start_change(self, app, current_value):
|
||||||
|
if current_value.endswith(ELLIPSIS):
|
||||||
|
app.action_start_edit()
|
||||||
|
else:
|
||||||
|
# default edit mode
|
||||||
|
app._show_input("edit", current_value)
|
||||||
|
|
||||||
|
def format_for_display(self, val):
|
||||||
|
val = str(val)
|
||||||
|
if "\n" in val:
|
||||||
|
val = val.split("\n")[0] + ELLIPSIS
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
class EnumColumnConfig(TableColumnConfig):
|
||||||
|
def __init__(self, field: str, display_name: str, enum, **kwargs):
|
||||||
|
super().__init__(field, display_name, **kwargs)
|
||||||
|
self.enum = enum
|
||||||
|
|
||||||
|
def preprocess(self, val):
|
||||||
|
if val in self.enum:
|
||||||
|
return val
|
||||||
|
else:
|
||||||
|
raise NotifyValidationError(f"Invalid value {val}. Use: {list(self.enum)}")
|
||||||
|
|
||||||
|
def format_for_display(self, val):
|
||||||
|
return get_color_enum(val, self.enum)
|
||||||
|
|
||||||
|
def start_change(self, app, current_value):
|
||||||
|
# a weird hack? pass app here and correct modal gets pushed
|
||||||
|
app.push_screen(ChoiceModal(self.enum, current_value), app.apply_change)
|
||||||
|
|
||||||
|
|
||||||
|
class DateColumnConfig(TableColumnConfig):
|
||||||
|
def preprocess(self, val):
|
||||||
|
try:
|
||||||
|
return datetime.datetime.strptime(val, "%Y-%m-%d")
|
||||||
|
except ValueError:
|
||||||
|
raise NotifyValidationError("Invalid date format. Use YYYY-MM-DD")
|
||||||
|
|
||||||
|
def format_for_display(self, val):
|
||||||
|
return get_colored_date(val)
|
||||||
|
|
||||||
|
def start_change(self, app, current_value):
|
||||||
|
app.push_screen(DateModal(current_value), app.apply_change)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_col_cls(field_type):
|
||||||
|
return {
|
||||||
|
"text": TableColumnConfig,
|
||||||
|
"enum": EnumColumnConfig,
|
||||||
|
"date": DateColumnConfig,
|
||||||
|
}[field_type]
|
@ -1,4 +1,3 @@
|
|||||||
import datetime
|
|
||||||
from textual.app import App
|
from textual.app import App
|
||||||
from textual.widgets import (
|
from textual.widgets import (
|
||||||
DataTable,
|
DataTable,
|
||||||
@ -13,86 +12,10 @@ from ..utils import (
|
|||||||
remove_rich_tag,
|
remove_rich_tag,
|
||||||
filter_to_string,
|
filter_to_string,
|
||||||
get_text_from_editor,
|
get_text_from_editor,
|
||||||
get_color_enum,
|
|
||||||
get_colored_date,
|
|
||||||
)
|
)
|
||||||
from .keymodal import KeyModal
|
from .keymodal import KeyModal
|
||||||
from .modals import ChoiceModal, DateModal, ConfirmModal
|
from .modals import ConfirmModal
|
||||||
|
from .columns import get_col_cls
|
||||||
|
|
||||||
class NotifyValidationError(Exception):
|
|
||||||
"""will notify and continue if raised"""
|
|
||||||
|
|
||||||
|
|
||||||
ELLIPSIS = "…"
|
|
||||||
|
|
||||||
class TableColumnConfig:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
field: str,
|
|
||||||
display_name: str,
|
|
||||||
*,
|
|
||||||
default=None,
|
|
||||||
enable_editor=False,
|
|
||||||
filterable=True,
|
|
||||||
read_only=False,
|
|
||||||
):
|
|
||||||
self.field = field
|
|
||||||
self.display_name = display_name
|
|
||||||
self.default = default
|
|
||||||
self.enable_editor = enable_editor
|
|
||||||
self.filterable = filterable
|
|
||||||
self.read_only = read_only
|
|
||||||
|
|
||||||
def preprocess(self, val):
|
|
||||||
return val # no-op
|
|
||||||
|
|
||||||
def start_change(self, app, current_value):
|
|
||||||
if current_value.endswith(ELLIPSIS):
|
|
||||||
app.action_start_edit()
|
|
||||||
else:
|
|
||||||
# default edit mode
|
|
||||||
app._show_input("edit", current_value)
|
|
||||||
|
|
||||||
def format_for_display(self, val):
|
|
||||||
val = str(val)
|
|
||||||
if "\n" in val:
|
|
||||||
val = val.split("\n")[0] + ELLIPSIS
|
|
||||||
return val
|
|
||||||
|
|
||||||
|
|
||||||
class EnumColumnConfig(TableColumnConfig):
|
|
||||||
def __init__(self, field: str, display_name: str, enum, **kwargs):
|
|
||||||
super().__init__(field, display_name, **kwargs)
|
|
||||||
self.enum = enum
|
|
||||||
|
|
||||||
def preprocess(self, val):
|
|
||||||
if val in self.enum:
|
|
||||||
return val
|
|
||||||
else:
|
|
||||||
raise NotifyValidationError(f"Invalid value {val}. Use: {list(self.enum)}")
|
|
||||||
|
|
||||||
def format_for_display(self, val):
|
|
||||||
return get_color_enum(val, self.enum)
|
|
||||||
|
|
||||||
def start_change(self, app, current_value):
|
|
||||||
# a weird hack? pass app here and correct modal gets pushed
|
|
||||||
app.push_screen(ChoiceModal(self.enum, current_value), app.apply_change)
|
|
||||||
|
|
||||||
|
|
||||||
class DateColumnConfig(TableColumnConfig):
|
|
||||||
def preprocess(self, val):
|
|
||||||
try:
|
|
||||||
return datetime.datetime.strptime(val, "%Y-%m-%d")
|
|
||||||
except ValueError:
|
|
||||||
raise NotifyValidationError("Invalid date format. Use YYYY-MM-DD")
|
|
||||||
|
|
||||||
def format_for_display(self, val):
|
|
||||||
return get_colored_date(val)
|
|
||||||
|
|
||||||
def start_change(self, app, current_value):
|
|
||||||
app.push_screen(DateModal(current_value), app.apply_change)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -187,11 +110,7 @@ class TableEditor(App):
|
|||||||
# set up columns
|
# set up columns
|
||||||
for col in view["columns"]:
|
for col in view["columns"]:
|
||||||
field_type = col.get("field_type", "text")
|
field_type = col.get("field_type", "text")
|
||||||
field_cls = {
|
field_cls = get_col_cls(field_type)
|
||||||
"text": TableColumnConfig,
|
|
||||||
"enum": EnumColumnConfig,
|
|
||||||
"date": DateColumnConfig,
|
|
||||||
}[field_type]
|
|
||||||
field_name = col["field_name"]
|
field_name = col["field_name"]
|
||||||
display_name = col.get("display_name", field_name.title())
|
display_name = col.get("display_name", field_name.title())
|
||||||
default = col.get("default")
|
default = col.get("default")
|
||||||
|
Loading…
Reference in New Issue
Block a user