Skip to content

Commit

Permalink
refactor: Reuse AsyncTable in Pods table
Browse files Browse the repository at this point in the history
  • Loading branch information
tiithansen committed Jun 10, 2024
1 parent c337b33 commit 418d6ea
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 367 deletions.
3 changes: 3 additions & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { GrafanaTheme2 } from "@grafana/data";

export type TextColor = keyof GrafanaTheme2['colors']['text'] | 'error' | 'success' | 'warning' | 'info'
39 changes: 27 additions & 12 deletions src/components/AsyncTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@ import { resolveVariable } from 'common/variableHelpers';
import { CellContext, ColumnDef, ColumnSort, Row } from '@tanstack/react-table';
import { FormattedCell } from 'pages/Workloads/components/FormattedCell';
import { SortingState } from 'common/sortingHelpers';
import { TextColor } from 'common/types';
import { isFunction } from 'lodash';

export type CellType = 'link' | 'formatted'
export type CellType = 'link' | 'formatted' | 'custom'

type LinkCellProps = {
urlBuilder?: (value: any) => string;
type LinkCellProps<TableRow> = {
urlBuilder?: (value: TableRow) => string;
}

export type FormattedCellProps = {
export type FormattedCellProps<TableRow> = {
decimals?: number;
format?: string;
color?: TextColor | ((row: TableRow) => TextColor)
}

export type CellProps = LinkCellProps | FormattedCellProps;
export type CellProps<TableRow> = LinkCellProps<TableRow> | FormattedCellProps<TableRow>;

export interface ColumnSortingConfig<TableRow> {
enabled: boolean;
Expand All @@ -42,11 +45,17 @@ export interface Column<TableRow> {
header: string;
accessor?: (row: TableRow) => any;
cellType?: CellType;
cellProps?: CellProps;
cellProps?: CellProps<TableRow>;
cellBuilder?: (row: TableRow) => React.JSX.Element;
sortingConfig: ColumnSortingConfig<TableRow>;
columns?: Array<Column<TableRow>>;
}

export interface QueryBuilder<TableRow> {
rootQueryBuilder: (variables: SceneVariables | SceneVariableSet, sorting: SortingState, sortingConfig: ColumnSortingConfig<TableRow>) => any;
rowQueryBuilder: (rows: TableRow[], variables: SceneVariables | SceneVariableSet) => any;
}

interface TableState<TableRow> extends SceneObjectState {
expandedRows?: SceneObject[];
asyncRowData?: Map<string, number[]>;
Expand All @@ -55,9 +64,8 @@ interface TableState<TableRow> extends SceneObjectState {
columns: Array<Column<TableRow>>;
createRowId: (row: TableRow) => string;
asyncDataRowMapper: (row: TableRow, asyncRowData: any) => void;
rootQueryBuilder: (variables: SceneVariables | SceneVariableSet, sorting: SortingState, sortingConfig: ColumnSortingConfig<TableRow>) => any;
rowQueryBuilder: (rows: TableRow[], variables: SceneVariables | SceneVariableSet) => any;
expandedRowBuilder?: (row: TableRow) => SceneObject;
queryBuilder: QueryBuilder<TableRow>;
}

interface ExpandedRowProps<TableRow> {
Expand Down Expand Up @@ -85,16 +93,23 @@ function mapColumn<TableRow>(column: Column<TableRow>): ColumnDef<TableRow> {
let cell = undefined;
switch (column.cellType) {
case 'link':
cell = (props: CellContext<TableRow, any>) => LinkCell('namespaces', props.row.getValue(column.id))
const linkCellProps = column.cellProps as LinkCellProps<TableRow>;
cell = (props: CellContext<TableRow, any>) => LinkCell(linkCellProps.urlBuilder ? linkCellProps.urlBuilder(props.row.original) : '', props.row.getValue(column.id))
break;
case 'formatted':
const formattedCellProps = column.cellProps as FormattedCellProps;
const formattedCellProps = column.cellProps as FormattedCellProps<TableRow>;
cell = (props: CellContext<TableRow, any>) => FormattedCell({
value: props.row.getValue(column.id),
decimals: formattedCellProps.decimals,
format: formattedCellProps.format,
color: (formattedCellProps.color && isFunction(formattedCellProps.color))
? formattedCellProps.color(props.row.original)
: formattedCellProps.color,
})
break;
case 'custom':
cell = (props: CellContext<TableRow, any>) => column.cellBuilder!(props.row.original)
break;
}

return {
Expand Down Expand Up @@ -170,7 +185,7 @@ export class AsyncTable<TableRow> extends SceneObjectBase<TableState<TableRow>>
},

queries: [
...this.state.rowQueryBuilder(rows.map(row => row.original), sceneVariables),
...this.state.queryBuilder.rowQueryBuilder(rows.map(row => row.original), sceneVariables),
],
$timeRange: timeRange.clone(),
}).then((data) => {
Expand All @@ -195,7 +210,7 @@ export class AsyncTable<TableRow> extends SceneObjectBase<TableState<TableRow>>
const sortingConfig = this.getColumnById(newSortingState.columnId)?.sortingConfig;

if (sortingConfig && sortingConfig.local === false) {
newState.$data = this.state.rootQueryBuilder(sceneGraph.getVariables(this), newSortingState, sortingConfig)
newState.$data = this.state.queryBuilder.rootQueryBuilder(sceneGraph.getVariables(this), newSortingState, sortingConfig)
}

this.setState(newState)
Expand Down
6 changes: 4 additions & 2 deletions src/components/ResourceBreakdownTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,10 @@ export const ResourceBreakdownTable = () => {
createRowId: (row) => `${row.namespace}:${row.cluster}`,
asyncDataRowMapper: rowMapper,
$data: createRootQuery(variables, defaultSorting),
rowQueryBuilder: createRowQueries,
rootQueryBuilder: createRootQuery,
queryBuilder: {
rowQueryBuilder: createRowQueries,
rootQueryBuilder: createRootQuery,
}
}),
}),
],
Expand Down
3 changes: 2 additions & 1 deletion src/pages/Clusters/tabs/Nodes/Nodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ import { getSeriesValue } from 'common/seriesHelpers';
import { createClusterVariable, resolveVariable } from 'common/variableHelpers';
import { LinkCell } from 'pages/Workloads/components/LinkCell';
import { CellContext } from '@tanstack/react-table';
import { FormattedCell, TextColor } from 'pages/Workloads/components/FormattedCell';
import { FormattedCell } from 'pages/Workloads/components/FormattedCell';
import { Metrics } from 'metrics/metrics';
import { TextColor } from 'common/types';

const clusterVariable = createClusterVariable();

Expand Down
2 changes: 1 addition & 1 deletion src/pages/Workloads/components/ContainersCell.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Text } from '@grafana/ui';

export const ContainersCellBuilder = ({ total, ready }: { total: number, ready: number }) => {
export const ContainersCell = ({ total, ready }: { total: number, ready: number }) => {

return (
<span>
Expand Down
5 changes: 2 additions & 3 deletions src/pages/Workloads/components/FormattedCell.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react';
import { Text } from '@grafana/ui';
import { GrafanaTheme2, getValueFormat } from '@grafana/data';

export type TextColor = keyof GrafanaTheme2['colors']['text'] | 'error' | 'success' | 'warning' | 'info'
import { getValueFormat } from '@grafana/data';
import { TextColor } from 'common/types';

export interface FormattedCellProps {
color?: TextColor;
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Workloads/components/LinkCell.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { TextLink } from "@grafana/ui";

export function LinkCell(url: string, id: string) {
return (<TextLink color="primary" href={`${url}/${id}${window.location.search}`}>{ id }</TextLink>);
export function LinkCell(url: string, text: string) {
return (<TextLink color="primary" href={`${url}${window.location.search}`}>{ text }</TextLink>);
}
Loading

0 comments on commit 418d6ea

Please sign in to comment.