Source code for webgrid.types
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional, Union
class ValidationError(Exception):
pass
class FieldValidationError(ValidationError):
def __init__(self, field, value, type_):
message = f'Received {field}={value}; should be of type {type_}'
super().__init__(message)
[docs]@dataclass
class Filter:
op: str
value1: Union[str, List[str]]
value2: Optional[str] = None
[docs]@dataclass
class Paging:
pager_on: bool = False
per_page: Optional[int] = None
on_page: Optional[int] = None
def __post_init__(self):
if self.per_page is not None and not isinstance(self.per_page, int):
raise FieldValidationError('per_page', self.per_page, 'int')
if self.on_page is not None and not isinstance(self.on_page, int):
raise FieldValidationError('on_page', self.on_page, 'int')
[docs]@dataclass
class Sort:
key: str
flag_desc: bool
[docs]@dataclass
class FilterOperator:
key: str
label: str
field_type: Optional[str]
hint: Optional[str] = None
[docs]@dataclass
class FilterOption:
key: str
value: str
[docs]@dataclass
class FilterSpec:
operators: List[FilterOperator]
primary_op: Optional[FilterOperator]
@dataclass
class OptionsFilterSpec(FilterSpec):
options: List[FilterOption]
[docs]@dataclass
class ColumnGroup:
label: str
columns: List[str]
@dataclass
class GridTotals:
page: Optional[Dict[str, Any]] = None
grand: Optional[Dict[str, Any]] = None
[docs]@dataclass
class GridSettings:
search_expr: Optional[str] = None
filters: Dict[str, Filter] = field(default_factory=dict)
paging: Paging = field(default_factory=Paging)
sort: List[Sort] = field(default_factory=list)
export_to: Optional[str] = None
[docs] @classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'GridSettings':
"""Create from deserialized json"""
try:
filters = {key: Filter(**filter_) for key, filter_ in data.get('filters', {}).items()}
except TypeError as e:
raise ValidationError(f'Filter: {e}')
try:
paging = Paging(**data.get('paging', {}))
except TypeError as e:
raise ValidationError(f'Paging: {e}')
try:
sort = [Sort(**sort) for sort in data.get('sort', [])]
except TypeError as e:
raise ValidationError(f'Sort: {e}')
return cls(
search_expr=data.get('search_expr'),
filters=filters,
paging=paging,
sort=sort,
export_to=data.get('export_to'),
)
[docs] def to_args(self) -> Dict[str, Any]:
"""Convert grid parameters to request args format"""
args = {
'search': self.search_expr,
'onpage': self.paging.on_page,
'perpage': self.paging.per_page,
'export_to': self.export_to,
}
for key, filter_ in self.filters.items():
args[f'op({key})'] = filter_.op
args[f'v1({key})'] = filter_.value1
if filter_.value2:
args[f'v2({key})'] = filter_.value2
for i, s in enumerate(self.sort, 1):
prefix = '-' if s.flag_desc else ''
args[f'sort{i}'] = f'{prefix}{s.key}'
return args
[docs]@dataclass
class GridSpec:
columns: List[Dict[str, str]]
column_groups: List[ColumnGroup]
column_types: List[Dict[str, str]]
export_targets: List[str]
enable_search: bool
enable_sort: bool
sortable_columns: List[str]
filters: Dict[str, FilterSpec] = field(default_factory=dict)
[docs]@dataclass
class GridState:
page_count: int
record_count: int
warnings: List[str]
[docs]@dataclass
class Grid:
settings: GridSettings
spec: GridSpec
state: GridState
records: List[Dict[str, Any]]
totals: GridTotals
errors: List[str]