mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 10:15:57 +08:00
[Feat]: threshold in table (#4002)
* feat: threshold in table * refactor: updated the message * chore: some css fixes
This commit is contained in:
parent
e7f9c3981b
commit
4009ac83fe
@ -1,4 +1,5 @@
|
|||||||
export enum Events {
|
export enum Events {
|
||||||
UPDATE_GRAPH_VISIBILITY_STATE = 'UPDATE_GRAPH_VISIBILITY_STATE',
|
UPDATE_GRAPH_VISIBILITY_STATE = 'UPDATE_GRAPH_VISIBILITY_STATE',
|
||||||
UPDATE_GRAPH_MANAGER_TABLE = 'UPDATE_GRAPH_MANAGER_TABLE',
|
UPDATE_GRAPH_MANAGER_TABLE = 'UPDATE_GRAPH_MANAGER_TABLE',
|
||||||
|
TABLE_COLUMNS_DATA = 'TABLE_COLUMNS_DATA',
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,12 @@ const GridPanelSwitch = forwardRef<
|
|||||||
yAxisUnit,
|
yAxisUnit,
|
||||||
thresholds,
|
thresholds,
|
||||||
},
|
},
|
||||||
[PANEL_TYPES.TABLE]: { ...GRID_TABLE_CONFIG, data: panelData, query },
|
[PANEL_TYPES.TABLE]: {
|
||||||
|
...GRID_TABLE_CONFIG,
|
||||||
|
data: panelData,
|
||||||
|
query,
|
||||||
|
thresholds,
|
||||||
|
},
|
||||||
[PANEL_TYPES.LIST]: null,
|
[PANEL_TYPES.LIST]: null,
|
||||||
[PANEL_TYPES.TRACE]: null,
|
[PANEL_TYPES.TRACE]: null,
|
||||||
[PANEL_TYPES.EMPTY_WIDGET]: null,
|
[PANEL_TYPES.EMPTY_WIDGET]: null,
|
||||||
|
@ -1,20 +1,86 @@
|
|||||||
|
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||||
|
import { Space, Tooltip } from 'antd';
|
||||||
|
import { Events } from 'constants/events';
|
||||||
import { QueryTable } from 'container/QueryTable';
|
import { QueryTable } from 'container/QueryTable';
|
||||||
import { memo } from 'react';
|
import { createTableColumnsFromQuery } from 'lib/query/createTableColumnsFromQuery';
|
||||||
|
import { memo, ReactNode, useEffect, useMemo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { eventEmitter } from 'utils/getEventEmitter';
|
||||||
|
|
||||||
import { WrapperStyled } from './styles';
|
import { WrapperStyled } from './styles';
|
||||||
import { GridTableComponentProps } from './types';
|
import { GridTableComponentProps } from './types';
|
||||||
|
import { findMatchingThreshold } from './utils';
|
||||||
|
|
||||||
function GridTableComponent({
|
function GridTableComponent({
|
||||||
data,
|
data,
|
||||||
query,
|
query,
|
||||||
|
thresholds,
|
||||||
...props
|
...props
|
||||||
}: GridTableComponentProps): JSX.Element {
|
}: GridTableComponentProps): JSX.Element {
|
||||||
|
const { t } = useTranslation(['valueGraph']);
|
||||||
|
const { columns, dataSource } = useMemo(
|
||||||
|
() =>
|
||||||
|
createTableColumnsFromQuery({
|
||||||
|
query,
|
||||||
|
queryTableData: data,
|
||||||
|
}),
|
||||||
|
[data, query],
|
||||||
|
);
|
||||||
|
|
||||||
|
const newColumnData = columns.map((e) => ({
|
||||||
|
...e,
|
||||||
|
render: (text: string): ReactNode => {
|
||||||
|
const isNumber = !Number.isNaN(Number(text));
|
||||||
|
if (thresholds && isNumber) {
|
||||||
|
const { hasMultipleMatches, threshold } = findMatchingThreshold(
|
||||||
|
thresholds,
|
||||||
|
e.title as string,
|
||||||
|
Number(text),
|
||||||
|
);
|
||||||
|
|
||||||
|
const idx = thresholds.findIndex(
|
||||||
|
(t) => t.thresholdTableOptions === e.title,
|
||||||
|
);
|
||||||
|
if (idx !== -1) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
threshold.thresholdFormat === 'Background'
|
||||||
|
? { backgroundColor: threshold.thresholdColor }
|
||||||
|
: { color: threshold.thresholdColor }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Space>
|
||||||
|
{text}
|
||||||
|
{hasMultipleMatches && (
|
||||||
|
<Tooltip title={t('this_value_satisfies_multiple_thresholds')}>
|
||||||
|
<ExclamationCircleFilled className="value-graph-icon" />
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return <div>{text}</div>;
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eventEmitter.emit(Events.TABLE_COLUMNS_DATA, {
|
||||||
|
columns: newColumnData,
|
||||||
|
dataSource,
|
||||||
|
});
|
||||||
|
}, [dataSource, newColumnData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WrapperStyled>
|
<WrapperStyled>
|
||||||
<QueryTable
|
<QueryTable
|
||||||
query={query}
|
query={query}
|
||||||
queryTableData={data}
|
queryTableData={data}
|
||||||
loading={false}
|
loading={false}
|
||||||
|
columns={newColumnData}
|
||||||
|
dataSource={dataSource}
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
import { TableProps } from 'antd';
|
import { TableProps } from 'antd';
|
||||||
import { LogsExplorerTableProps } from 'container/LogsExplorerTable/LogsExplorerTable.interfaces';
|
import { LogsExplorerTableProps } from 'container/LogsExplorerTable/LogsExplorerTable.interfaces';
|
||||||
|
import {
|
||||||
|
ThresholdOperators,
|
||||||
|
ThresholdProps,
|
||||||
|
} from 'container/NewWidget/RightContainer/Threshold/types';
|
||||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
export type GridTableComponentProps = { query: Query } & Pick<
|
export type GridTableComponentProps = {
|
||||||
LogsExplorerTableProps,
|
query: Query;
|
||||||
'data'
|
thresholds?: ThresholdProps[];
|
||||||
> &
|
} & Pick<LogsExplorerTableProps, 'data'> &
|
||||||
Omit<TableProps<RowData>, 'columns' | 'dataSource'>;
|
Omit<TableProps<RowData>, 'columns' | 'dataSource'>;
|
||||||
|
|
||||||
|
export type RequiredThresholdProps = Omit<
|
||||||
|
ThresholdProps,
|
||||||
|
'thresholdTableOptions' | 'thresholdOperator' | 'thresholdValue'
|
||||||
|
> & {
|
||||||
|
thresholdTableOptions: string;
|
||||||
|
thresholdOperator: ThresholdOperators;
|
||||||
|
thresholdValue: number;
|
||||||
|
};
|
||||||
|
58
frontend/src/container/GridTableComponent/utils.ts
Normal file
58
frontend/src/container/GridTableComponent/utils.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
|
||||||
|
|
||||||
|
// Helper function to evaluate the condition based on the operator
|
||||||
|
function evaluateCondition(
|
||||||
|
operator: string | undefined,
|
||||||
|
value: number,
|
||||||
|
thresholdValue: number,
|
||||||
|
): boolean {
|
||||||
|
switch (operator) {
|
||||||
|
case '>':
|
||||||
|
return value > thresholdValue;
|
||||||
|
case '<':
|
||||||
|
return value < thresholdValue;
|
||||||
|
case '>=':
|
||||||
|
return value >= thresholdValue;
|
||||||
|
case '<=':
|
||||||
|
return value <= thresholdValue;
|
||||||
|
case '==':
|
||||||
|
return value === thresholdValue;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findMatchingThreshold(
|
||||||
|
thresholds: ThresholdProps[],
|
||||||
|
label: string,
|
||||||
|
value: number,
|
||||||
|
): {
|
||||||
|
threshold: ThresholdProps;
|
||||||
|
hasMultipleMatches: boolean;
|
||||||
|
} {
|
||||||
|
const matchingThresholds: ThresholdProps[] = [];
|
||||||
|
let hasMultipleMatches = false;
|
||||||
|
|
||||||
|
thresholds.forEach((threshold) => {
|
||||||
|
if (
|
||||||
|
threshold.thresholdValue !== undefined &&
|
||||||
|
threshold.thresholdTableOptions === label &&
|
||||||
|
evaluateCondition(
|
||||||
|
threshold.thresholdOperator,
|
||||||
|
value,
|
||||||
|
threshold.thresholdValue,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
matchingThresholds.push(threshold);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingThresholds.length > 1) {
|
||||||
|
hasMultipleMatches = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
threshold: matchingThresholds[0],
|
||||||
|
hasMultipleMatches,
|
||||||
|
};
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
.show-case-container {
|
.show-case-container {
|
||||||
padding: 5px 15px;
|
padding: 5px 15px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.show-case-dark {
|
.show-case-dark {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable sonarjs/cognitive-complexity */
|
||||||
import './Threshold.styles.scss';
|
import './Threshold.styles.scss';
|
||||||
|
|
||||||
import { CheckOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
|
import { CheckOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
|
||||||
@ -40,6 +41,8 @@ function Threshold({
|
|||||||
moveThreshold,
|
moveThreshold,
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
thresholdLabel = '',
|
thresholdLabel = '',
|
||||||
|
tableOptions,
|
||||||
|
thresholdTableOptions = '',
|
||||||
}: ThresholdProps): JSX.Element {
|
}: ThresholdProps): JSX.Element {
|
||||||
const [isEditMode, setIsEditMode] = useState<boolean>(isEditEnabled);
|
const [isEditMode, setIsEditMode] = useState<boolean>(isEditEnabled);
|
||||||
const [operator, setOperator] = useState<string | number>(
|
const [operator, setOperator] = useState<string | number>(
|
||||||
@ -52,6 +55,9 @@ function Threshold({
|
|||||||
thresholdFormat,
|
thresholdFormat,
|
||||||
);
|
);
|
||||||
const [label, setLabel] = useState<string>(thresholdLabel);
|
const [label, setLabel] = useState<string>(thresholdLabel);
|
||||||
|
const [tableSelectedOption, setTableSelectedOption] = useState<string>(
|
||||||
|
thresholdTableOptions,
|
||||||
|
);
|
||||||
|
|
||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
|
|
||||||
@ -72,6 +78,7 @@ function Threshold({
|
|||||||
thresholdUnit: unit,
|
thresholdUnit: unit,
|
||||||
thresholdValue: value,
|
thresholdValue: value,
|
||||||
thresholdLabel: label,
|
thresholdLabel: label,
|
||||||
|
thresholdTableOptions: tableSelectedOption,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return threshold;
|
return threshold;
|
||||||
@ -104,6 +111,10 @@ function Threshold({
|
|||||||
setFormat(value);
|
setFormat(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleTableOptionsChange = (value: string): void => {
|
||||||
|
setTableSelectedOption(value);
|
||||||
|
};
|
||||||
|
|
||||||
const deleteHandler = (): void => {
|
const deleteHandler = (): void => {
|
||||||
if (thresholdDeleteHandler) {
|
if (thresholdDeleteHandler) {
|
||||||
thresholdDeleteHandler(index);
|
thresholdDeleteHandler(index);
|
||||||
@ -203,7 +214,11 @@ function Threshold({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Space>
|
<Space
|
||||||
|
direction={
|
||||||
|
selectedGraph === PANEL_TYPES.TABLE ? 'vertical' : 'horizontal'
|
||||||
|
}
|
||||||
|
>
|
||||||
{selectedGraph === PANEL_TYPES.TIME_SERIES && (
|
{selectedGraph === PANEL_TYPES.TIME_SERIES && (
|
||||||
<>
|
<>
|
||||||
<Typography.Text>Label</Typography.Text>
|
<Typography.Text>Label</Typography.Text>
|
||||||
@ -219,10 +234,31 @@ function Threshold({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{selectedGraph === PANEL_TYPES.VALUE && (
|
{(selectedGraph === PANEL_TYPES.VALUE ||
|
||||||
|
selectedGraph === PANEL_TYPES.TABLE) && (
|
||||||
<>
|
<>
|
||||||
<Typography.Text>If value is</Typography.Text>
|
<Typography.Text>
|
||||||
|
If value {selectedGraph === PANEL_TYPES.TABLE ? 'in' : 'is'}
|
||||||
|
</Typography.Text>
|
||||||
{isEditMode ? (
|
{isEditMode ? (
|
||||||
|
<>
|
||||||
|
{selectedGraph === PANEL_TYPES.TABLE && (
|
||||||
|
<Space>
|
||||||
|
<Select
|
||||||
|
style={{
|
||||||
|
minWidth: '150px',
|
||||||
|
backgroundColor,
|
||||||
|
borderRadius: '5px',
|
||||||
|
}}
|
||||||
|
defaultValue={tableSelectedOption}
|
||||||
|
options={tableOptions}
|
||||||
|
bordered={!isDarkMode}
|
||||||
|
showSearch
|
||||||
|
onChange={handleTableOptionsChange}
|
||||||
|
/>
|
||||||
|
<Typography.Text>is</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
<Select
|
<Select
|
||||||
style={{ minWidth: '73px', backgroundColor }}
|
style={{ minWidth: '73px', backgroundColor }}
|
||||||
defaultValue={operator}
|
defaultValue={operator}
|
||||||
@ -230,8 +266,17 @@ function Threshold({
|
|||||||
onChange={handleOperatorChange}
|
onChange={handleOperatorChange}
|
||||||
bordered={!isDarkMode}
|
bordered={!isDarkMode}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
<>
|
||||||
|
{selectedGraph === PANEL_TYPES.TABLE && (
|
||||||
|
<Space>
|
||||||
|
<ShowCaseValue width="150px" value={tableSelectedOption} />
|
||||||
|
<Typography.Text>is</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
<ShowCaseValue width="49px" value={operator} />
|
<ShowCaseValue width="49px" value={operator} />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -280,7 +325,7 @@ function Threshold({
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<ShowCaseValue width="100px" value={<CustomColor color={color} />} />
|
<ShowCaseValue width="120px" value={<CustomColor color={color} />} />
|
||||||
<ShowCaseValue width="100px" value={format} />
|
<ShowCaseValue width="100px" value={format} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import './ThresholdSelector.styles.scss';
|
import './ThresholdSelector.styles.scss';
|
||||||
|
|
||||||
import { Button, Typography } from 'antd';
|
import { Button, Typography } from 'antd';
|
||||||
import { useCallback } from 'react';
|
import { ColumnsType } from 'antd/es/table';
|
||||||
|
import { Events } from 'constants/events';
|
||||||
|
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { DndProvider } from 'react-dnd';
|
import { DndProvider } from 'react-dnd';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
|
import { eventEmitter } from 'utils/getEventEmitter';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
import Threshold from './Threshold';
|
import Threshold from './Threshold';
|
||||||
@ -15,6 +19,22 @@ function ThresholdSelector({
|
|||||||
yAxisUnit,
|
yAxisUnit,
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
}: ThresholdSelectorProps): JSX.Element {
|
}: ThresholdSelectorProps): JSX.Element {
|
||||||
|
const [tableOptions, setTableOptions] = useState<
|
||||||
|
Array<{ value: string; label: string }>
|
||||||
|
>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
eventEmitter.on(
|
||||||
|
Events.TABLE_COLUMNS_DATA,
|
||||||
|
(data: { columns: ColumnsType<RowData>; dataSource: RowData[] }) => {
|
||||||
|
const newTableOptions = data.columns.map((e) => ({
|
||||||
|
value: e.title as string,
|
||||||
|
label: e.title as string,
|
||||||
|
}));
|
||||||
|
setTableOptions([...newTableOptions]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const moveThreshold = useCallback(
|
const moveThreshold = useCallback(
|
||||||
(dragIndex: number, hoverIndex: number) => {
|
(dragIndex: number, hoverIndex: number) => {
|
||||||
setThresholds((prevCards) => {
|
setThresholds((prevCards) => {
|
||||||
@ -44,6 +64,7 @@ function ThresholdSelector({
|
|||||||
moveThreshold,
|
moveThreshold,
|
||||||
keyIndex: thresholds.length,
|
keyIndex: thresholds.length,
|
||||||
selectedGraph,
|
selectedGraph,
|
||||||
|
thresholdTableOptions: tableOptions[0]?.value || '',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@ -75,6 +96,8 @@ function ThresholdSelector({
|
|||||||
moveThreshold={moveThreshold}
|
moveThreshold={moveThreshold}
|
||||||
selectedGraph={selectedGraph}
|
selectedGraph={selectedGraph}
|
||||||
thresholdLabel={threshold.thresholdLabel}
|
thresholdLabel={threshold.thresholdLabel}
|
||||||
|
tableOptions={tableOptions}
|
||||||
|
thresholdTableOptions={threshold.thresholdTableOptions}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<Button className="threshold-selector-button" onClick={addThresholdHandler}>
|
<Button className="threshold-selector-button" onClick={addThresholdHandler}>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import { Dispatch, ReactNode, SetStateAction } from 'react';
|
import { Dispatch, ReactNode, SetStateAction } from 'react';
|
||||||
|
|
||||||
type ThresholdOperators = '>' | '<' | '>=' | '<=' | '=';
|
export type ThresholdOperators = '>' | '<' | '>=' | '<=' | '=';
|
||||||
|
|
||||||
export type ThresholdProps = {
|
export type ThresholdProps = {
|
||||||
index: string;
|
index: string;
|
||||||
@ -14,9 +14,11 @@ export type ThresholdProps = {
|
|||||||
thresholdFormat?: 'Text' | 'Background';
|
thresholdFormat?: 'Text' | 'Background';
|
||||||
isEditEnabled?: boolean;
|
isEditEnabled?: boolean;
|
||||||
thresholdLabel?: string;
|
thresholdLabel?: string;
|
||||||
|
thresholdTableOptions?: string;
|
||||||
setThresholds?: Dispatch<SetStateAction<ThresholdProps[]>>;
|
setThresholds?: Dispatch<SetStateAction<ThresholdProps[]>>;
|
||||||
moveThreshold: (dragIndex: number, hoverIndex: number) => void;
|
moveThreshold: (dragIndex: number, hoverIndex: number) => void;
|
||||||
selectedGraph: PANEL_TYPES;
|
selectedGraph: PANEL_TYPES;
|
||||||
|
tableOptions?: Array<{ value: string; label: string }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ShowCaseValueProps = {
|
export type ShowCaseValueProps = {
|
||||||
|
@ -24,7 +24,7 @@ export const showAsOptions: DefaultOptionType[] = [
|
|||||||
export const panelTypeVsThreshold: { [key in PANEL_TYPES]: boolean } = {
|
export const panelTypeVsThreshold: { [key in PANEL_TYPES]: boolean } = {
|
||||||
[PANEL_TYPES.TIME_SERIES]: true,
|
[PANEL_TYPES.TIME_SERIES]: true,
|
||||||
[PANEL_TYPES.VALUE]: true,
|
[PANEL_TYPES.VALUE]: true,
|
||||||
[PANEL_TYPES.TABLE]: false,
|
[PANEL_TYPES.TABLE]: true,
|
||||||
[PANEL_TYPES.LIST]: false,
|
[PANEL_TYPES.LIST]: false,
|
||||||
[PANEL_TYPES.TRACE]: false,
|
[PANEL_TYPES.TRACE]: false,
|
||||||
[PANEL_TYPES.EMPTY_WIDGET]: false,
|
[PANEL_TYPES.EMPTY_WIDGET]: false,
|
||||||
|
@ -16,4 +16,6 @@ export type QueryTableProps = Omit<
|
|||||||
modifyColumns?: (columns: ColumnsType<RowData>) => ColumnsType<RowData>;
|
modifyColumns?: (columns: ColumnsType<RowData>) => ColumnsType<RowData>;
|
||||||
renderColumnCell?: Record<string, (record: RowData) => ReactNode>;
|
renderColumnCell?: Record<string, (record: RowData) => ReactNode>;
|
||||||
downloadOption?: DownloadOptions;
|
downloadOption?: DownloadOptions;
|
||||||
|
columns?: ColumnsType<RowData>;
|
||||||
|
dataSource?: RowData[];
|
||||||
};
|
};
|
||||||
|
@ -17,25 +17,35 @@ export function QueryTable({
|
|||||||
modifyColumns,
|
modifyColumns,
|
||||||
renderColumnCell,
|
renderColumnCell,
|
||||||
downloadOption,
|
downloadOption,
|
||||||
|
columns,
|
||||||
|
dataSource,
|
||||||
...props
|
...props
|
||||||
}: QueryTableProps): JSX.Element {
|
}: QueryTableProps): JSX.Element {
|
||||||
const { isDownloadEnabled = false, fileName = '' } = downloadOption || {};
|
const { isDownloadEnabled = false, fileName = '' } = downloadOption || {};
|
||||||
const { servicename } = useParams<IServiceName>();
|
const { servicename } = useParams<IServiceName>();
|
||||||
const { loading } = props;
|
const { loading } = props;
|
||||||
const { columns, dataSource } = useMemo(
|
const { columns: newColumns, dataSource: newDataSource } = useMemo(() => {
|
||||||
() =>
|
if (columns && dataSource) {
|
||||||
createTableColumnsFromQuery({
|
return { columns, dataSource };
|
||||||
|
}
|
||||||
|
return createTableColumnsFromQuery({
|
||||||
query,
|
query,
|
||||||
queryTableData,
|
queryTableData,
|
||||||
renderActionCell,
|
renderActionCell,
|
||||||
renderColumnCell,
|
renderColumnCell,
|
||||||
}),
|
});
|
||||||
[query, queryTableData, renderActionCell, renderColumnCell],
|
}, [
|
||||||
);
|
columns,
|
||||||
|
dataSource,
|
||||||
|
query,
|
||||||
|
queryTableData,
|
||||||
|
renderActionCell,
|
||||||
|
renderColumnCell,
|
||||||
|
]);
|
||||||
|
|
||||||
const downloadableData = createDownloadableData(dataSource);
|
const downloadableData = createDownloadableData(newDataSource);
|
||||||
|
|
||||||
const tableColumns = modifyColumns ? modifyColumns(columns) : columns;
|
const tableColumns = modifyColumns ? modifyColumns(newColumns) : newColumns;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="query-table">
|
<div className="query-table">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user