Tables & Filters Design
Document Type: Domain Design (Tier 2) Domain: TABLES, FILTERS Domain Character: Thin orchestration SRS Reference: tables.md, filters.md Status: Draft Last Updated: 2026-01-25
1. Overview
1.1 Purpose
The Tables & Filters subsystem provides reusable infrastructure for displaying, sorting, filtering, and paginating tabular data throughout the application. It defines the generic patterns that all domain-specific table implementations consume.
This is a thin orchestration domain that:
- Provides generic table display components (headers, rows, selection)
- Provides pagination infrastructure (page navigation, items per page)
- Provides sorting infrastructure (column-based ordering)
- Provides filtering infrastructure (criteria-based data constraint)
- Coordinates backend traits and frontend components
Individual table implementations (Runs, Audits, Wells, etc.) define context-specific behaviors by consuming these generic patterns.
1.2 Requirements Covered
| REQ ID | Title | Priority |
|---|---|---|
| REQ-TABLES-001 | Display Data in Tabular Format | Must |
| REQ-TABLES-002 | Sort Table Data by Column | Must |
| REQ-TABLES-003 | Select and Interact with Table Rows | Must |
| REQ-TABLES-004 | Navigate Paginated Data | Must |
| REQ-TABLES-005 | Handle Large Data Exports | Must |
| REQ-TABLES-006 | Configure Column Visibility | Must |
| REQ-FILTERS-001 | Filter Data by Criteria | Must |
1.3 Constraints
Tier 2 Constraint: This document describes ownership, patterns, and design rationale. Domain-specific table configurations are owned by their respective domains. See Database Reference for schema details.
1.4 Dependencies
| Direction | Domain/Component | Purpose |
|---|---|---|
| Provides to | All table-using domains | Sorting, filtering, pagination infrastructure |
| Consumes | Laravel Framework | LengthAwarePaginator, Query Builder |
| Consumes | Background Jobs | Large export handling |
2. Component Architecture
2.1 Component Diagram
2.2 Component Responsibilities
| Component | Layer | Responsibility | REQ Trace |
|---|---|---|---|
Sortable | Backend Trait | Applies column-based ordering to queries | REQ-TABLES-002 |
Filterable | Backend Trait | Delegates filter application to filter classes | REQ-FILTERS-001 |
BaseFilters | Backend Class | Request-to-query filter dispatch infrastructure | REQ-FILTERS-001 |
LengthAwarePaginator | Laravel | Provides pagination metadata (total, per_page, current_page) | REQ-TABLES-004 |
TableHandler | Frontend View | Orchestrates paginator/infinite loader selection | REQ-TABLES-004, 005 |
NewPaginator | Frontend Component | Page navigation controls, items per page | REQ-TABLES-004 |
FlexTableHeader | Frontend Component | Sticky column headers | REQ-TABLES-001 |
FlexTableRow | Frontend Component | Row display, selection state | REQ-TABLES-001, 003 |
ColumnVisibilityPicker | Frontend Component | Column show/hide dialog | REQ-TABLES-006 |
PaginatorRowsPerPagePicker | Frontend Component | Items per page dropdown (10, 20, 30, 50, All) | REQ-TABLES-004 |
PaginatorGoToPage | Frontend Component | Direct page number input | REQ-TABLES-004 |
3. Data Design
3.1 Entities
This domain does not own persistent entities. It provides infrastructure consumed by other domains.
3.2 Data Structures
Pagination Response (Backend → Frontend)
interface PaginatedResponse<T> {
data: T[];
current_page: number;
last_page: number;
per_page: number;
total: number;
}
Pagination State (Frontend)
interface PaginatedData<T> {
data: T[];
current_page: number;
per_page: number;
total: number;
rangeOfRecords: string; // e.g., "1-20"
}
Column Visibility State
interface ColumnVisibility {
[columnKey: string]: boolean;
}
Sort Direction Convention
Ascending: field_name (no prefix)
Descending: -field_name (hyphen prefix)
3.3 State Transitions
This domain is stateless. Pagination, sort, and filter state are request-scoped parameters.
4. Interface Design
4.1 APIs Provided
Query Parameter Conventions (consumed by all table endpoints)
| Parameter | Format | Purpose |
|---|---|---|
sort | field or -field | Column to sort by, descending if prefixed with - |
per_page | integer | Items per page (default: 20) |
page | integer | Current page number |
[filter_name] | varies | Filter-specific criteria |
4.2 APIs Consumed
All domain-specific endpoints consuming table infrastructure use Laravel's standard pagination response format.
4.3 Events
| Event | Direction | Purpose |
|---|---|---|
@input | ColumnVisibilityPicker → Parent | Visibility changes confirmed |
@changed-per-page | NewPaginator → Parent | User changed items per page |
@requested-all-records | NewPaginator → TableHandler | User requested all records |
5. Behavioral Design
5.1 Sort Application
Algorithm: Apply Sort to Query
Inputs:
- query: Eloquent Builder
- order: string - Field name, optionally prefixed with '-'
- table: string (optional) - Table name for qualified column
Outputs:
- query: Eloquent Builder with ORDER BY applied
Steps:
1. If order starts with '-':
a. direction = 'desc'
b. field = order without leading '-'
2. Else:
a. direction = 'asc'
b. field = order
3. Apply ORDER BY table.field direction to query
4. Return query
Notes:
- Table name defaults to model's table if not specified
- Single-column sort only (new sort clears previous)
5.2 Filter Application
Algorithm: Apply Filters to Query
Inputs:
- builder: Eloquent Builder
- request: HTTP Request containing filter parameters
Outputs:
- builder: Eloquent Builder with WHERE clauses applied
Steps:
1. For each request parameter (name, value):
a. Convert name to camelCase
b. If method exists on filter class:
- If value is set: call method(value)
- Else: call method()
c. Else: skip parameter
2. Return modified builder
Notes:
- Multiple filters combine with AND logic
- Domain-specific filter classes extend BaseFilters
- Filter methods modify $this->builder directly
5.3 Pagination Flow
5.4 Column Visibility
Algorithm: Toggle Column Visibility
Inputs:
- columnVisibility: Record<string, boolean> - Current state
- columnKey: string - Column to toggle
Outputs:
- Updated visibility state (on confirm only)
Steps:
1. User opens column visibility picker
2. Clone current visibility state to local state
3. User toggles individual columns
4. On Save: emit updated state to parent
5. On Cancel: discard local changes
Notes:
- Visibility persisted in component state (not server)
- Hidden columns remain filterable
6. Error Handling
| Condition | Detection | Response | User Impact |
|---|---|---|---|
| API timeout | Network error | Display error message | Table shows error state |
| Invalid page number | Page > last_page | Navigate to page 1 | First page displayed |
| Export timeout | Large dataset | Offer truncate/background options | User chooses export strategy |
| Filter timeout | Complex criteria | Display timeout message | User refines criteria |
7. Configuration
| Setting | Location | Default | Effect |
|---|---|---|---|
paginator_per_page | User settings | 20 | User's preferred items per page |
max_realtime_export_records | Application | 1000 | Threshold for synchronous export |
See Configuration Reference for details.
8. Implementation Mapping
8.1 Code Locations
Backend Components
| Component | Type | Path |
|---|---|---|
| Sortable | Trait | code/app/Sortable.php |
| Filterable | Trait | code/app/Filterable.php |
| BaseFilters | Class | code/app/Filters/BaseFilters.php |
| RunFilters | Class | code/app/Filters/RunFilters.php |
| AuditFilters | Class | code/app/Filters/AuditFilters.php |
| WellFilters | Class | code/app/Filters/WellFilters.php |
| ReportFilters*Controllers | Controllers | code/app/Http/Controllers/ReportFilters/ |
Frontend Components
| Component | Type | Path |
|---|---|---|
| TableHandler | View | code/resources/frontend/src/views/TableHandler.vue |
| NewPaginator | Component | code/resources/frontend/src/components/paginator/NewPaginator.vue |
| PaginatorRowsPerPagePicker | Component | code/resources/frontend/src/components/paginator/PaginatorRowsPerPagePicker.vue |
| PaginatorGoToPage | Component | code/resources/frontend/src/components/paginator/PaginatorGoToPage.vue |
| FlexTableHeader | Component | code/resources/frontend/src/components/table-components/FlexTableHeader.vue |
| FlexTableRow | Component | code/resources/frontend/src/components/table-components/FlexTableRow.vue |
| ColumnVisibilityPicker | Component | code/resources/frontend/src/components/column-visibility/ColumnVisibilityPicker.vue |
| TableWrapper | Component | code/resources/frontend/src/components/common/TableWrapper.vue |
8.2 Requirement Traceability
| REQ ID | Design Section | Code Location |
|---|---|---|
| REQ-TABLES-001 | §2.2 Component Responsibilities | FlexTableHeader.vue, FlexTableRow.vue, TableWrapper.vue |
| REQ-TABLES-002 | §5.1 Sort Application | Sortable.php |
| REQ-TABLES-003 | §2.2 (FlexTableRow) | FlexTableRow.vue (isSelected prop, @click handler) |
| REQ-TABLES-004 | §5.3 Pagination Flow | NewPaginator.vue, PaginatorRowsPerPagePicker.vue, PaginatorGoToPage.vue |
| REQ-TABLES-005 | §6 Error Handling | TableHandler.vue (handleRequestAllRecords), domain-specific export jobs |
| REQ-TABLES-006 | §5.4 Column Visibility | ColumnVisibilityPicker.vue |
| REQ-FILTERS-001 | §5.2 Filter Application | Filterable.php, BaseFilters.php, domain-specific filter classes |
9. Design Decisions
| Decision | Rationale | Alternatives Considered |
|---|---|---|
| Trait-based sorting/filtering | Composable; models opt-in to capabilities | Base model class (rejected: less flexible) |
| Backend filtering with frontend display | Large datasets require server-side processing | Client-side filtering (rejected: memory limits) |
| Single-column sort | Simplicity; multi-column rarely needed | Multi-column sort (rejected: complexity) |
| Items per page in user settings | User preference persistence | Session storage (rejected: less persistent) |
| Sort direction via hyphen prefix | Compact URL representation | Separate direction param (rejected: more verbose) |
10. Related Documents
| Document | Relevant Sections |
|---|---|
| SRS: tables.md | Requirements source for TABLES |
| SRS: filters.md | Requirements source for FILTERS |
| SDS: Architecture | Component patterns |
| SDS: RUNFILE Domain | Example consumer (Runs table) |
| SDS: AUDIT Domain | Example consumer (Audits table) |
| SDS: REPORTS Domain | Example consumer (LJ/Trends reports) |