MDK Logo

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} />
}
@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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/alerts/current-alerts/alert-confirmation-modal/alert-confirmation-modal.tsx

Props

PropStatusType / OptionsDefaultDescription
isOpenRequiredboolean-Controls dialog visibility
onOkRequiredVoidFunction-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/features/alerts/alerts/alerts.tsx

Props

PropStatusType / OptionsDefaultDescription
classNameOptionalstring-Extra class on the page wrapper
dateRangeOptionalHistoricalAlertsRangelast 14 daysControlled date range for the historical alerts. Defaults to last 14 days
devicesOptionalDevice[]-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
headerOptionalReact.ReactNode-Optional header (e.g. breadcrumbs) rendered above the alerts
historicalAlertsOptionalAlert[]-Pre-fetched historical alerts log entries
initialSeverityOptionalstring-Initial severity selection (typically derived from ?severity= URL param)
isCurrentAlertsLoadingOptionalbooleanfalseLoading flag for the "Current Alerts" table
isDemoModeOptionalbooleanfalseWhen true, sound notifications are skipped (e.g. demo / preview)
isHistoricalAlertsEnabledOptionalbooleanfalseWhen true, shows the "Historical Alerts Log" section. Mirrors the alertsHistoricalLogEnabled feature flag in the source app
isHistoricalAlertsLoadingOptionalbooleanfalseLoading flag for the historical log
isSoundEnabledOptionalbooleanfalseWhether sound notifications are enabled in user preferences
onAlertClickOptional((id?: string | undefined, uuid?: string | undefined) => void)-Callback invoked when the operator clicks an alert row. Receives the device id and alert uuid
onDateRangeChangeOptional((range: HistoricalAlertsRange) => void)-Called when the operator picks a new historical range
selectedAlertIdOptionalstring-Optional alert id used to focus on a single alert (deep-link from URL)
typeFiltersForSiteOptionalCascaderOption[]-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/alerts/alerts-table-title/alerts-table-title.tsx

Props

PropStatusType / OptionsDefaultDescription
titleRequiredReact.ReactNode-Section heading
classNameOptionalstring-Additional CSS class
subtitleOptionalReact.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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/alerts/current-alerts/current-alerts.tsx

Props

PropStatusType / OptionsDefaultDescription
filterTagsRequiredstring[]-Search tags (controlled). Mirrors the redux selectFilterTags slice in the source app
localFiltersRequiredAlertLocalFilters-Filters controlled outside (typically by URL severity param)
onFilterTagsChangeRequired(tags: string[]) => void-Setter for the tags above
onLocalFiltersChangeRequired(filters: AlertLocalFilters) => void-Setter for the filters above
classNameOptionalstring-Additional class names
devicesOptionalDevice[]-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
isDemoModeOptionalbooleanfalseSkip sound entirely (e.g. in demo/preview environments)
isLoadingOptionalbooleanfalseShow DataTable loading overlay
isSoundEnabledOptionalbooleanfalseWhether sound notifications are enabled in user preferences (e.g. theme slice)
onAlertClickOptional((id?: string | undefined, uuid?: string | undefined) => void)-Click handler when the user opens an alert (right arrow icon in the row)
selectedAlertIdOptionalstring-Optional id used to focus on a single alert (deep-link from URL)
typeFiltersForSiteOptionalCascaderOption[]-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/primitives/components/data-table/USAGE.md#props-detail

Props

PropStatusType / OptionsDefaultDescription
columnsRequiredColumnDef<I, any>[]-The column configuration table. See https://tanstack.com/table/v8/docs/guide/column-defs
dataRequiredI[]-The data to be shown in the table. See https://tanstack.com/table/v8/docs/guide/data
borderedOptionalbooleanfalseAdd borders to all cells
canRowExpandOptional((row: Row<I>) => boolean)falseCallback to check if a row can be expanded
contentClassNameOptionalstring-Classname of the content element
defaultSortingOptionalSortingState[]Default sorting applied when the table is first mounted (uncontrolled mode). Ignored when sorting is provided
enableMultiRowSelectionOptionalbooleantrueEnables selection of multiple rows
enablePaginationOptionalbooleantrueShow pagination
enableRowExpansionOptionalbooleanfalseShow a columns with a button which can expand the row
enableRowSelectionOptionalboolean | ((row: Row<I>) => boolean)falseShow a checkbox column and enables selection
expandedRowsOptionalExpandedState-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
fullWidthOptionalbooleantrueIs table full width
getRowIdOptional((row: I, index: number, parent?: Row<I> | undefined) => string)indexGet the row ID for a row. If not specified index is the default row ID
loadingOptionalbooleanfalseShow a loading indicator overlay
onExpandedRowsChangeOptional((expandedRows: ExpandedState) => void)-Callback to be called when the rows are expanded or collapsed
onPaginationChangeOptional((pagination: PaginationState) => void)-Callback to be called when the pagination params change
onRowClickOptional((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
onSelectionsChangeOptional((selections: RowSelectionState) => void)-Callback to be called when the row are selected / unselected
onSortingChangeOptional((sorting: SortingState) => void)-Callback to be called when the sorting changes
paginationOptionalPaginationStateundefinedSpecify the pagination params. Object of shape { pageIndex: number, pageSize: number }. If undefined then the pagination is managed internally
renderExpandedContentOptional((row: Row<I>) => React.ReactNode)-Render the content of the expanded row. Required when enableRowExpansion is true
selectionsOptionalRowSelectionStateundefinedSpecify 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
sortingOptionalSortingStateundefinedSpecify the sorting params. If undefined then the sorting is managed internally
tableClassNameOptionalstring-Classname of the table element
wrapperClassNameOptionalstring-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/device-explorer/device-explorer.tsx

Props

PropStatusType / OptionsDefaultDescription
dataRequiredDevice[]-Rows
deviceTypeRequired"container" | "miner" | "cabinet"-Active device-type tab
filterOptionsRequiredDeviceExplorerFilterOption[]-Filter category definitions
getFormattedDateRequired(date: Date) => string-Date formatter from the host's timezone setup
onDeviceTypeChangeRequired(type: DeviceExplorerDeviceType) => void-Setter for the device type
onFiltersChangeRequired(value: LocalFilters) => void-Setter for filters
onSearchTagsChangeRequired(tags: string[]) => void-Setter for search tags
renderActionRequired(device: Device) => React.ReactNode-Renderer for the per-row action cell
searchOptionsRequiredDeviceExplorerSearchOption[]-Searchable column definitions
searchTagsRequiredstring[]-Active search-tag chips
classNameOptionalstring-Additional class names
filtersOptionalLocalFilters-Controlled filter values
onRowClickOptional((device: Device) => void)-Called when a row is clicked (e.g. to open the device's detail page)
onSelectedDevicesChangeOptional((selections: RowSelectionState) => void)-Setter for row selection
onSortingChangeOptional((sorting: SortingState) => void)--
selectedDevicesOptionalRowSelectionState-Controlled row-selection state

EfficiencyMinerTypeView

Efficiency drilldown grouped by miner model — J/TH and uptime for each model in the fleet

agent-ready

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/reporting-tool/operational/efficiency/tabs/miner-type-view/miner-type-view.tsx

Props

PropStatusType / OptionsDefaultDescription
chartInputOptionalToBarChartDataInput{ series: [] }Bar chart series data
isEmptyOptionalbooleanfalseShows the empty state instead of the chart
isLoadingOptionalbooleanfalseLoading state
onTimeFrameChangeOptional((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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/reporting-tool/operational/efficiency/tabs/miner-unit-view/miner-unit-view.tsx

Props

PropStatusType / OptionsDefaultDescription
chartInputOptionalToBarChartDataInput{ series: [] }Bar chart series data
isEmptyOptionalbooleanfalseShows the empty state instead of the chart
isLoadingOptionalbooleanfalseLoading state
onTimeFrameChangeOptional((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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/reporting-tool/operational/efficiency/tabs/site-view/site-view.tsx

Props

PropStatusType / OptionsDefaultDescription
avgEfficiencyOptionalnumber | nullnullAverage efficiency value
dateRangeOptionalEfficiencyDateRange-Selected date range
isLoadingOptionalbooleanfalseLoading state
logOptionalMetricsEfficiencyLogEntry[][]Efficiency log entries
nominalValueOptionalnumber | nullnullNominal target efficiency
onDateRangeChangeOptional((range: EfficiencyDateRange) => void)-Date range change handler
onResetOptionalVoidFunction-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/alerts/historical-alerts/historical-alerts.tsx

Props

PropStatusType / OptionsDefaultDescription
dateRangeRequiredHistoricalAlertsRange-Selected date range for the historical query (controlled)
filterTagsRequiredstring[]-Shared with CurrentAlerts
localFiltersRequiredAlertLocalFilters-Filters and search tags coming from the parent (typically shared with CurrentAlerts)
onDateRangeChangeRequired(range: HistoricalAlertsRange) => void-Setter for the date range
alertsOptionalAlert[][]Pre-fetched historical alerts log entries (each with a thing device payload)
classNameOptionalstring-Additional class names
isLoadingOptionalbooleanfalseShow DataTable loading overlay
onAlertClickOptional((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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/reporting-tool/operational/efficiency/efficiency.tsx

Props

PropStatusType / OptionsDefaultDescription
defaultTabOptional"site-view" | "miner-type-view" | "mining-unit-view""site-view"Initially selected tab
minerTypeViewOptionalEfficiencyMinerTypeViewProps-Props forwarded to EfficiencyMinerTypeView
minerUnitViewOptionalEfficiencyMinerUnitViewProps-Props forwarded to EfficiencyMinerUnitView
siteViewOptionalEfficiencySiteViewProps-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/features/pool-manager/miner-explorer/pool-manager-miner-explorer.tsx

Props

PropStatusType / OptionsDefaultDescription
backButtonClickRequiredVoidFunction-Called when the operator clicks the "Pool Manager" back link
minersRequiredListThingsDevice[]-Miners to render in the explorer table
poolConfigRequiredPoolConfigEntry[]-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/features/pool-manager/pools/pool-manager-pools.tsx

Props

PropStatusType / OptionsDefaultDescription
backButtonClickRequiredVoidFunction-Called when the operator clicks the "Pool Manager" back link
poolConfigRequiredPoolConfigEntry[]-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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/repairs/repair-log-changes-sub-row.tsx

Props

PropStatusType / OptionsDefaultDescription
batchActionRequiredobject-The repair batch action whose part changes should be displayed
devicesRequiredPartial<{ id: string; rack: string; info: Partial<{ serialNum: string; macAddress: string; }>; }>[]-Devices referenced by the batch action, pre-fetched by the parent
isLoadingOptionalbooleanfalseShow 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

Source

https://github.com/tetherto/mdk/blob/main/ui/packages/react-devkit/src/domain/components/alerts/tag-filter-bar/tag-filter-bar.tsx

Props

PropStatusType / OptionsDefaultDescription
filterTagsRequiredstring[]-Active tag filter values
localFiltersRequiredAlertLocalFilters-Current local filter state
onLocalFiltersChangeRequired(filters: AlertLocalFilters) => void-Called when any local filter changes
onSearchTagsChangeRequired(tags: string[]) => void-Called when tag filter changes
classNameOptionalstring-Additional CSS class
placeholderOptionalstring-Search input placeholder
typeFiltersForSiteOptionalCascaderOption[]-Site-specific overrides for the "type" filter children. If provided, the "Type" filter group will use these instead of the defaults

On this page