Table
Data tables, grids, and tabular display components
Components for displaying and interacting with tabular data.
Prerequisites
- Complete the installation
- Add the dependency to your app's
package.json
{
"dependencies": {
"@tetherto/mdk-react-devkit": "*",
"@tetherto/mdk-react-adapter": "*",
"@tetherto/mdk-ui-foundation": "*"
}
}Run npm install from the mdk/ui workspace root after your app is under apps/ so npm links workspace packages.
- Import styles:
import '@tetherto/mdk-react-devkit/styles.css'
Components
@tetherto/mdk-react-devkit
Data table
import { DataTable } from '@tetherto/mdk-react-devkit'Sortable, paginated, optionally selectable / expandable table built on TanStack React Table. Controlled and uncontrolled modes for each piece of state.
Data contracts
DataTableColumnDef, DataTableRow, DataTableSortingState,
DataTablePaginationState, DataTableRowSelectionState, DataTableExpandedState
are re-exported from @tetherto/mdk-react-devkit.
Example
/**
* Runnable example for DataTable.
*/
import type { DataTableColumnDef } from '@tetherto/mdk-react-devkit'
import { DataTable } from '@tetherto/mdk-react-devkit'
type Miner = {
id: string
status: 'online' | 'warning' | 'offline'
hashrate: number
power_w: number
}
const data: Miner[] = [
{ id: 'miner-01', status: 'online', hashrate: 102.4, power_w: 3200 },
{ id: 'miner-02', status: 'warning', hashrate: 95.1, power_w: 3450 },
{ id: 'miner-03', status: 'offline', hashrate: 0, power_w: 0 },
]
const columns: DataTableColumnDef<Miner, unknown>[] = [
{ accessorKey: 'id', header: 'Miner' },
{ accessorKey: 'status', header: 'Status' },
{ accessorKey: 'hashrate', header: 'Hashrate (TH/s)' },
{ accessorKey: 'power_w', header: 'Power (W)' },
]
export const DataTableExample = () => {
return <DataTable<Miner> data={data} columns={columns} getRowId={(row) => row.id} />
}Related API
@tetherto/mdk-react-devkit
Import the public APIs on this page from @tetherto/mdk-react-devkit.
AlertConfirmationModal
Modal that confirms acknowledging or clearing one or more alerts before applying the change
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
isOpen | Required | boolean | - | Controls dialog visibility |
onOk | Required | VoidFunction | - | Called when the user confirms the action |
Alerts
Full alerts page — combines the searchable current-alerts table, an optional historical-alerts log section, severity filters, and the sound confirmation modal. Wraps CurrentAlerts and HistoricalAlerts and coordinates their shared filter / date-range / selected-id state.
Must be rendered inside <MdkProvider> — the embedded tables read tag filters from the devices store and use the timezone formatter hook
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
className | Optional | string | - | Extra class on the page wrapper |
dateRange | Optional | HistoricalAlertsRange | last 14 days | Controlled date range for the historical alerts. Defaults to last 14 days |
devices | Optional | Device[] | - | Devices powering the "Current Alerts" table — a flat list of rows that carry last.alerts. Any backend that can produce that shape works; there is no response envelope to reproduce |
header | Optional | React.ReactNode | - | Optional header (e.g. breadcrumbs) rendered above the alerts |
historicalAlerts | Optional | Alert[] | - | Pre-fetched historical alerts log entries |
initialSeverity | Optional | string | - | Initial severity selection (typically derived from ?severity= URL param) |
isCurrentAlertsLoading | Optional | boolean | false | Loading flag for the "Current Alerts" table |
isDemoMode | Optional | boolean | false | When true, sound notifications are skipped (e.g. demo / preview) |
isHistoricalAlertsEnabled | Optional | boolean | false | When true, shows the "Historical Alerts Log" section. Mirrors the alertsHistoricalLogEnabled feature flag in the source app |
isHistoricalAlertsLoading | Optional | boolean | false | Loading flag for the historical log |
isSoundEnabled | Optional | boolean | false | Whether sound notifications are enabled in user preferences |
onAlertClick | Optional | ((id?: string | undefined, uuid?: string | undefined) => void) | - | Callback invoked when the operator clicks an alert row. Receives the device id and alert uuid |
onDateRangeChange | Optional | ((range: HistoricalAlertsRange) => void) | - | Called when the operator picks a new historical range |
selectedAlertId | Optional | string | - | Optional alert id used to focus on a single alert (deep-link from URL) |
typeFiltersForSite | Optional | CascaderOption[] | - | Optional site-specific overrides for the type filter |
AlertsTableTitle
Title strip for an alerts table with the section heading and an optional count badge
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
title | Required | React.ReactNode | - | Section heading |
className | Optional | string | - | Additional CSS class |
subtitle | Optional | React.ReactNode | - | Optional subtitle or count badge |
CurrentAlerts
Sortable, searchable data table of currently active alerts derived from a raw devices payload. Plays an audible beep when a critical alert is present (gated by isSoundEnabled + user confirmation modal)
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
filterTags | Required | string[] | - | Search tags (controlled). Mirrors the redux selectFilterTags slice in the source app |
localFilters | Required | AlertLocalFilters | - | Filters controlled outside (typically by URL severity param) |
onFilterTagsChange | Required | (tags: string[]) => void | - | Setter for the tags above |
onLocalFiltersChange | Required | (filters: AlertLocalFilters) => void | - | Setter for the filters above |
className | Optional | string | - | Additional class names |
devices | Optional | Device[] | - | Devices carrying alerts (last.alerts), as a flat list. Unwrapping any backend envelope is the data layer's job, not this component's. Shape mirrors the API response from the source app |
isDemoMode | Optional | boolean | false | Skip sound entirely (e.g. in demo/preview environments) |
isLoading | Optional | boolean | false | Show DataTable loading overlay |
isSoundEnabled | Optional | boolean | false | Whether sound notifications are enabled in user preferences (e.g. theme slice) |
onAlertClick | Optional | ((id?: string | undefined, uuid?: string | undefined) => void) | - | Click handler when the user opens an alert (right arrow icon in the row) |
selectedAlertId | Optional | string | - | Optional id used to focus on a single alert (deep-link from URL) |
typeFiltersForSite | Optional | CascaderOption[] | - | Optional site-specific overrides for the type filter |
DataTable
Generic typed data table built on TanStack React Table. Supports pagination, sorting, expansion, row selection and custom column renderers
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
columns | Required | ColumnDef<I, any>[] | - | The column configuration table. See https://tanstack.com/table/v8/docs/guide/column-defs |
data | Required | I[] | - | The data to be shown in the table. See https://tanstack.com/table/v8/docs/guide/data |
bordered | Optional | boolean | false | Add borders to all cells |
canRowExpand | Optional | ((row: Row<I>) => boolean) | false | Callback to check if a row can be expanded |
contentClassName | Optional | string | - | Classname of the content element |
defaultSorting | Optional | SortingState | [] | Default sorting applied when the table is first mounted (uncontrolled mode). Ignored when sorting is provided |
enableMultiRowSelection | Optional | boolean | true | Enables selection of multiple rows |
enablePagination | Optional | boolean | true | Show pagination |
enableRowExpansion | Optional | boolean | false | Show a columns with a button which can expand the row |
enableRowSelection | Optional | boolean | ((row: Row<I>) => boolean) | false | Show a checkbox column and enables selection |
expandedRows | Optional | ExpandedState | - | Specify the expanded rows If undefined, the expansions are managed internally Object with the key of row ID and a boolean specifying if the row is selected. The default row ID is the index. This can be changed using getRowId prop |
fullWidth | Optional | boolean | true | Is table full width |
getRowId | Optional | ((row: I, index: number, parent?: Row<I> | undefined) => string) | index | Get the row ID for a row. If not specified index is the default row ID |
loading | Optional | boolean | false | Show a loading indicator overlay |
onExpandedRowsChange | Optional | ((expandedRows: ExpandedState) => void) | - | Callback to be called when the rows are expanded or collapsed |
onPaginationChange | Optional | ((pagination: PaginationState) => void) | - | Callback to be called when the pagination params change |
onRowClick | Optional | ((rowData: I) => void) | - | Called when a body row is clicked. When set, rows become interactive (pointer cursor, role="button", keyboard-activatable with Enter/Space). Clicks originating from an interactive control in the row (button, link, input, checkbox, or anything marked data-no-row-click) are ignored, so the selection checkbox and expand toggle keep working independently |
onSelectionsChange | Optional | ((selections: RowSelectionState) => void) | - | Callback to be called when the row are selected / unselected |
onSortingChange | Optional | ((sorting: SortingState) => void) | - | Callback to be called when the sorting changes |
pagination | Optional | PaginationState | undefined | Specify the pagination params. Object of shape { pageIndex: number, pageSize: number }. If undefined then the pagination is managed internally |
renderExpandedContent | Optional | ((row: Row<I>) => React.ReactNode) | - | Render the content of the expanded row. Required when enableRowExpansion is true |
selections | Optional | RowSelectionState | undefined | Specify the selected rows. If undefined, the selections are managed internally Object with the key of row ID and a boolean specifying if the row is selected. The default row ID is the index. This can be changed using getRowId prop |
sorting | Optional | SortingState | undefined | Specify the sorting params. If undefined then the sorting is managed internally |
tableClassName | Optional | string | - | Classname of the table element |
wrapperClassName | Optional | string | - | Classname of the wrapper element |
DeviceExplorer
Top-level device explorer: filter toolbar + searchable, sortable table of miners, containers, or cabinets. Designed to be controlled by URL state in the host app
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
data | Required | Device[] | - | Rows |
deviceType | Required | "container" | "miner" | "cabinet" | - | Active device-type tab |
filterOptions | Required | DeviceExplorerFilterOption[] | - | Filter category definitions |
getFormattedDate | Required | (date: Date) => string | - | Date formatter from the host's timezone setup |
onDeviceTypeChange | Required | (type: DeviceExplorerDeviceType) => void | - | Setter for the device type |
onFiltersChange | Required | (value: LocalFilters) => void | - | Setter for filters |
onSearchTagsChange | Required | (tags: string[]) => void | - | Setter for search tags |
renderAction | Required | (device: Device) => React.ReactNode | - | Renderer for the per-row action cell |
searchOptions | Required | DeviceExplorerSearchOption[] | - | Searchable column definitions |
searchTags | Required | string[] | - | Active search-tag chips |
className | Optional | string | - | Additional class names |
filters | Optional | LocalFilters | - | Controlled filter values |
onRowClick | Optional | ((device: Device) => void) | - | Called when a row is clicked (e.g. to open the device's detail page) |
onSelectedDevicesChange | Optional | ((selections: RowSelectionState) => void) | - | Setter for row selection |
onSortingChange | Optional | ((sorting: SortingState) => void) | - | - |
selectedDevices | Optional | RowSelectionState | - | Controlled row-selection state |
EfficiencyMinerTypeView
Efficiency drilldown grouped by miner model — J/TH and uptime for each model in the fleet
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
chartInput | Optional | ToBarChartDataInput | { series: [] } | Bar chart series data |
isEmpty | Optional | boolean | false | Shows the empty state instead of the chart |
isLoading | Optional | boolean | false | Loading state |
onTimeFrameChange | Optional | ((start: Date, end: Date) => void) | - | Fired when the time-frame selector changes |
EfficiencyMinerUnitView
Efficiency drilldown by individual miner serial — outliers and worst-performers surface here
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
chartInput | Optional | ToBarChartDataInput | { series: [] } | Bar chart series data |
isEmpty | Optional | boolean | false | Shows the empty state instead of the chart |
isLoading | Optional | boolean | false | Loading state |
onTimeFrameChange | Optional | ((start: Date, end: Date) => void) | - | Fired when the time-frame selector changes |
EfficiencySiteView
Site-level efficiency view — site-aggregate J/TH, uptime, and capacity utilisation cards
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
avgEfficiency | Optional | number | null | null | Average efficiency value |
dateRange | Optional | EfficiencyDateRange | - | Selected date range |
isLoading | Optional | boolean | false | Loading state |
log | Optional | MetricsEfficiencyLogEntry[] | [] | Efficiency log entries |
nominalValue | Optional | number | null | null | Nominal target efficiency |
onDateRangeChange | Optional | ((range: EfficiencyDateRange) => void) | - | Date range change handler |
onReset | Optional | VoidFunction | - | Reset handler |
HistoricalAlerts
Sortable data table of historical alerts within a controlled date range. Renders a header with title + DateRangePicker, then the table
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
dateRange | Required | HistoricalAlertsRange | - | Selected date range for the historical query (controlled) |
filterTags | Required | string[] | - | Shared with CurrentAlerts |
localFilters | Required | AlertLocalFilters | - | Filters and search tags coming from the parent (typically shared with CurrentAlerts) |
onDateRangeChange | Required | (range: HistoricalAlertsRange) => void | - | Setter for the date range |
alerts | Optional | Alert[] | [] | Pre-fetched historical alerts log entries (each with a thing device payload) |
className | Optional | string | - | Additional class names |
isLoading | Optional | boolean | false | Show DataTable loading overlay |
onAlertClick | Optional | ((id?: string | undefined, uuid?: string | undefined) => void) | - | Called when the user opens an alert |
OperationsEfficiency
Top-level operations-efficiency section of the report — composes the site/type/unit views
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
defaultTab | Optional | "site-view" | "miner-type-view" | "mining-unit-view" | "site-view" | Initially selected tab |
minerTypeView | Optional | EfficiencyMinerTypeViewProps | - | Props forwarded to EfficiencyMinerTypeView |
minerUnitView | Optional | EfficiencyMinerUnitViewProps | - | Props forwarded to EfficiencyMinerUnitView |
siteView | Optional | EfficiencySiteViewProps | - | Props forwarded to EfficiencySiteView |
PoolManagerMinerExplorer
Pool-manager miner explorer page — searchable / filterable table of miners with multi-select and an "Assign Pool" bulk action. Submits the chosen pool change as a pending action via the adapter actions store, then opens a confirmation modal.
Must be rendered inside <MdkProvider> — the page uses useActions, useCheckPerm, and useContextualModal from @tetherto/mdk-react-adapter
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
backButtonClick | Required | VoidFunction | - | Called when the operator clicks the "Pool Manager" back link |
miners | Required | ListThingsDevice[] | - | Miners to render in the explorer table |
poolConfig | Required | PoolConfigEntry[] | - | Pool configurations powering the "Assign Pool" dropdown |
PoolManagerPools
Pool-manager pools page — accordion list of every configured pool with header summary (name, status, priority) and an expandable body (per-pool stats, edit, delete). Optional "Add Pool" CTA is gated by the ADD_POOL_ENABLED feature flag.
Must be rendered inside <MdkProvider> — the embedded "Add Pool" modal uses the contextual-modal adapter hook
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
backButtonClick | Required | VoidFunction | - | Called when the operator clicks the "Pool Manager" back link |
poolConfig | Required | PoolConfigEntry[] | - | Array of pool configurations to render |
RepairLogChangesSubRow
Expandable sub-row that lists the spare-part changes recorded in a repair batch action. Each non-miner repair action is resolved against its device to show the part type, serial number, MAC address, and whether the part was added or removed. Device data is fetched by the parent and passed in via props — the component does no data fetching itself
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
batchAction | Required | object | - | The repair batch action whose part changes should be displayed |
devices | Required | Partial<{ id: string; rack: string; info: Partial<{ serialNum: string; macAddress: string; }>; }>[] | - | Devices referenced by the batch action, pre-fetched by the parent |
isLoading | Optional | boolean | false | Show a spinner while the parent is still fetching devices |
TagFilterBar
Horizontal strip of removable tag chips that narrow a list view; clicking a chip removes the filter
agent-ready
Props
| Prop | Status | Type / Options | Default | Description |
|---|---|---|---|---|
filterTags | Required | string[] | - | Active tag filter values |
localFilters | Required | AlertLocalFilters | - | Current local filter state |
onLocalFiltersChange | Required | (filters: AlertLocalFilters) => void | - | Called when any local filter changes |
onSearchTagsChange | Required | (tags: string[]) => void | - | Called when tag filter changes |
className | Optional | string | - | Additional CSS class |
placeholder | Optional | string | - | Search input placeholder |
typeFiltersForSite | Optional | CascaderOption[] | - | Site-specific overrides for the "type" filter children. If provided, the "Type" filter group will use these instead of the defaults |