MATIH Platform is in active MVP development. Documentation reflects current implementation status.
15. Workbench Architecture
Filter System

Filter System

The BI Workbench filter system at frontend/bi-workbench/src/components/filters/ provides 7 filter types that can be composed into a FilterBar for interactive dashboard filtering. Filters support cascading dependencies, dynamic option loading, and URL synchronization.


FilterBar

File: frontend/bi-workbench/src/components/filters/FilterBar.tsx

The main container that renders all configured filters in order with reset and apply controls.

interface FilterBarProps {
  filters: DashboardFilter[];
  filterValues: FilterState;
  getFilterOptions: (filter: DashboardFilter) => FilterOption[];
  isLoadingOptions: (filterId: string) => boolean;
  onFilterChange: (filterId: string, value: unknown) => void;
  onReset: () => void;
  onApply?: () => void;
}

The FilterBar sorts filters by displayOrder and renders them via a FilterRenderer function that selects the appropriate component based on filter type.

Filter Types

TypeComponentFileValue Type
SINGLE_SELECTSingleSelectFilterSingleSelectFilter.tsxstring
MULTI_SELECTMultiSelectFilterMultiSelectFilter.tsxstring[]
DATE_RANGEDateRangeFilterDateRangeFilter.tsx{ from: string; to: string }
DATE_SINGLEDateSingleFilterDateSingleFilter.tsxstring
NUMBER_RANGENumberRangeFilterNumberRangeFilter.tsx{ min: number; max: number }
TEXT_SEARCHTextSearchFilterTextSearchFilter.tsxstring
BOOLEANBooleanFilterBooleanFilter.tsxboolean

Filter State Management

Filter state is managed through the useFilters hook:

// frontend/bi-workbench/src/hooks/useFilters.ts
const {
  filterValues,
  setFilterValue,
  resetFilters,
  applyFilters,
  getFilterOptions,
  isLoadingOptions,
} = useFilters(dashboardFilters);

Widget-Filter Bindings

Each widget defines filterBindings that map dashboard filter IDs to widget query parameters:

interface Widget {
  // ...
  filterBindings: Record<string, string>;  // filterId -> queryParam
  parameterBindings: Record<string, string>;
}

When a filter value changes, all widgets with matching bindings re-execute their queries with the new filter values.