Roster View
A roster view presents resource-by-shift scheduling data as a grid. Each row in the source table is rendered as a resource (e.g. an employee, machine, or room) and the columns are the shifts (e.g. days, time slots, or allocation buckets) being rostered. Cell contents are rendered with shared Card templates registered on the view.
A roster is composed of three parts:
Resource column — the leftmost column identifying each row’s resource.
Shift columns — one column per slot being rostered, appearing after the resource column in the order they are added.
Summary column — an optional rightmost column showing per-row aggregates (e.g. total hours).
Cards rendered in a shift column can optionally be made drag-and-droppable by
attaching a RosterTaskDefinition to the
column. Drags are always within a single column — dragging a card from one
row onto another row of the same column swaps the configured fields between
those two rows.
Basic setup
Create the view, set the resource and (optional) summary columns, and add one shift column per slot being rostered:
roster_view = builder.add_roster_view(
source_table=roster_table, display_name="Weekly Roster"
)
roster_view.set_resource_column(
RosterColumn(table_field_reference=roster_table.get_field("employee"))
)
for shift in ("mon", "tue", "wed"):
roster_view.add_shift_column(
table_field_reference=roster_table.get_field(f"shift_{shift}"),
minimum_width="120px",
)
Card templates and per-column bindings
A single Card template is typically reused across every shift column.
Placeholders in the template (e.g. ${[start]}) are filled in per-column
by mapping each placeholder to that column’s source field:
shift_card = Card()
shift_card.add_element(Text("${[start]} - ${[end]}"))
roster_view.add_card_template("shift", shift_card)
for shift in ("mon", "tue", "wed"):
column = roster_view.add_shift_column(
default_card_template_key="shift", minimum_width="120px"
)
column.add_template_field_mapping(
TemplateBindingKey("[start]"), roster_table.get_field(f"start_{shift}")
)
column.add_template_field_mapping(
TemplateBindingKey("[end]"), roster_table.get_field(f"end_{shift}")
)
Drag-and-drop
The helper below builds drag-and-drop configuration for one shift column of
a roster. Each shift has its own set of per-column fields (availability,
location, start/end times, capability lists), so the helper is parameterised
by shift and called once per shift column.
def build_shift_drag_and_drop(
roster_table: Table, shift: str
) -> RosterTaskDefinition:
"""Drag-and-drop config for one shift column of a roster."""
task_def = RosterTaskDefinition(
enable_drag_and_drop_field=roster_table.get_field(f"available_{shift}"),
highlight_whole_column_on_drag=True,
)
# Fields whose values are exchanged between the source and target
# rows on drop. The column's table_field_reference is typically a
# calculation that recomputes from these — include it here only if
# it is a data field that should also move.
for field_name in (
f"location_{shift}",
f"start_time_{shift}",
f"end_time_{shift}",
):
task_def.add_swap_field(roster_table.get_field(field_name))
# Gate valid drop targets: a drop is only allowed when the target
# row's <capability> array contains the dragged card's <required>
# value, for each pair below.
requirements = [
(f"location_{shift}", f"location_options_{shift}"),
(f"shift_type_{shift}", f"shift_type_options_{shift}"),
]
for required, capability in requirements:
task_def.add_requirement(
required_field=roster_table.get_field(required),
capability_field=roster_table.get_field(capability),
)
return task_def
# Attach to a shift column on the roster view:
monday = roster_view.add_shift_column(
table_field_reference=roster_table.get_field("monday_shift"),
minimum_width="80px",
)
monday.set_task_definition(build_shift_drag_and_drop(roster_table, "monday"))
API Reference
- class RosterView(source_table, display_name=None, hidden=False)[source]
Bases:
BaseView,FilterableViewResource-by-shift tabular view.
Each row in source_table is rendered as a resource row; the columns are the resource column (leftmost identifier), the shift columns (one per slot being rostered), and an optional summary column.
- source_table
Table ID of the source table whose rows back the roster.
- card_templates
Shared Card templates, keyed by the strings referenced from RosterColumn.default_card_template_key and RosterColumn.header_card_template_key.
- resource_column
Leftmost column identifying each row’s resource. Required for the view to be valid.
- shift_columns
Ordered list of shift columns appearing after the resource column.
- summary_column
Optional rightmost column showing per-row aggregates.
- freeze_headers
If True, the header row stays fixed while the body scrolls vertically.
- set_resource_column(col)[source]
Set the resource (leftmost) column. Returns self for chaining.
- Return type:
RosterView
- set_summary_column(col)[source]
Set the optional summary (rightmost) column. Returns self for chaining.
- Return type:
RosterView
- set_freeze_headers(freeze_headers)[source]
Set whether the header row stays fixed during vertical scrolling.
- Return type:
RosterView
- set_use_filter(use_filter)[source]
Attach a FilterComponent to this view and display its UI.
Sets both the bound filter (use_filter) and the displayed filter (show_filter) to use_filter.filter_name.
- Return type:
RosterView
- add_card_template(key, card)[source]
Register a shared card template on the view.
Card templates are looked up by key from RosterColumn.default_card_template_key and RosterColumn.header_card_template_key.
- Parameters:
key (
str) – Unique identifier referenced from RosterColumn template keys.card (
Card) – Card defining the template’s layout and content.
- add_shift_column(table_field_reference=None, default_card_template_key=None, header_card_template_key=None, minimum_width=None)[source]
Append a shift column to the roster.
At least one of table_field_reference and default_card_template_key must be supplied. Any card-template keys provided must already be registered via add_card_template.
- Parameters:
table_field_reference (
Field|None) – Source-table Field providing this column’s value.default_card_template_key (
str|None) – Key of the card template used to render normal cells.header_card_template_key (
str|None) – Optional key of the card template used to render the header.minimum_width (
str|None) – Optional CSS minimum width (e.g."80px").
- Return type:
RosterColumn- Returns:
The newly created RosterColumn, already appended to shift_columns.
- Raises:
ValueError – If a referenced card-template key is not registered, or if neither table_field_reference nor default_card_template_key is provided.
- class RosterColumn(table_field_reference=None, default_card_template_key=None, header_card_template_key=None, minimum_width=None)[source]
Bases:
BuildableConfiguration for a single column within a RosterView.
A column either binds directly to a source-table field (via table_field_reference) or renders its cells with a card template (via default_card_template_key); at least one of the two must be supplied.
- table_field_reference
Field ID of the source-table field providing this column’s value. Required unless default_card_template_key is set.
- default_card_template_key
Key of a card template registered on the parent RosterView used to render normal (non-header) cells for this column.
- header_card_template_key
Optional card-template key used to render the column header.
- minimum_width
Optional CSS width hint (e.g.
"120px") setting the column’s minimum width.
- template_field_mappings
Card-template placeholder keys (TemplateBindingKey) mapped to the model Field/Calculation/Parameter strings substituted in at render time.
- model_event_mappings
Card-template placeholder keys mapped to ModelEvent instances fired when the corresponding UI element is activated.
- task_definition
Optional RosterTaskDefinition configuring drag-and-drop behaviour for the cards rendered in this column. Has no effect on rendering or data binding.
- add_template_field_mapping(key, value)[source]
Bind a card-template placeholder to a model value.
- Parameters:
key (
TemplateBindingKey) – Placeholder key declared in the card template.value (
Field|Calculation|Parameter) – Field, Calculation, or Parameter whose string form is substituted into the template at render time.
- Return type:
RosterColumn- Returns:
This RosterColumn, for fluent chaining.
- add_model_event_mapping(key, event)[source]
Bind a card-template placeholder to a ModelEvent.
- Parameters:
key (
TemplateBindingKey) – Placeholder key representing an interactive element in the card template.event (
ModelEvent) – ModelEvent fired when that element is activated.
- Return type:
RosterColumn- Returns:
This RosterColumn, for fluent chaining.
- set_task_definition(task_definition)[source]
Attach drag-and-drop configuration for cards in this column.
- Parameters:
task_definition (
RosterTaskDefinition) – RosterTaskDefinition describing draggability, which fields swap between rows on drop, and requirement/capability matching for valid drop targets.- Return type:
RosterColumn- Returns:
This RosterColumn, for fluent chaining.
- class RosterTaskDefinition(enable_drag_and_drop_field, highlight_whole_column_on_drag)[source]
Bases:
BuildableDrag-and-drop configuration for the cards rendered in a roster column.
Attached to a RosterColumn via RosterColumn.set_task_definition(…), this describes only how cards in that column behave when the user drags them — it does not affect rendering, data binding, or which fields are displayed.
Drags are always within a single column: a card is dragged from one row onto another row of the same column, and the drop swaps the values of the configured swap_fields between those two rows. The column’s table_field_reference is typically a calculation that recomputes naturally from the swapped values; if it is a data field that should also move, add it to swap_fields explicitly.
- enable_drag_and_drop_field
Field ID of a per-row boolean field on the source table that gates whether a given card is draggable.
- highlight_whole_column_on_drag
UI hint controlling drop-target highlighting. If True, every card in the column is shaded green/red up-front (so the user can see which rows are valid drops before dragging over them). If False, only the card currently hovered is highlighted.
- swap_fields
Complete list of field IDs whose values are swapped between the source and target rows when a drop occurs.
- required_value_fields
Field IDs on the dragged card carrying scalar requirement values. Paired positionally with capability_fields to gate which target rows are valid drop targets: a drop is only permitted when, for every index
i, the target row’s capability_fields[i] (an array) contains the dragged card’s required_value_fields[i] (a scalar of the matching type).
- capability_fields
Field IDs on the target row holding array-valued capabilities, aligned positionally with required_value_fields.
- __init__(enable_drag_and_drop_field, highlight_whole_column_on_drag)[source]
- add_swap_field(field)[source]
Register a field whose value is swapped between the source and target rows on drop.
- Parameters:
field (
Field) – Field whose value moves with the card: on drop, the source row’s value and the target row’s value are exchanged.- Return type:
RosterTaskDefinition
- add_requirement(required_field, capability_field)[source]
Add a (requirement, capability) pair gating valid drop targets.
A drop is only permitted when the target row’s capability_field (an array) contains the dragged card’s required_field value (a scalar). The capability field’s data type must therefore be the array form of the required field’s data type.
- Parameters:
- Raises:
ValueError – If capability_field’s data type is not the array form of required_field’s data type.
- Return type:
RosterTaskDefinition