chore: wip - support onCellFilterAdded
This commit is contained in:
@@ -1,38 +1,40 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { capitalize, groupBy } from 'lodash';
|
||||
import { useCallback, useEffect, useState, useRef, useMemo } from 'react';
|
||||
import * as React from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { usePrevious, useUnmount } from 'react-use';
|
||||
|
||||
import {
|
||||
SplitOpen,
|
||||
LogRowModel,
|
||||
LogsMetaItem,
|
||||
DataFrame,
|
||||
AbsoluteTimeRange,
|
||||
GrafanaTheme2,
|
||||
LoadingState,
|
||||
TimeZone,
|
||||
RawTimeRange,
|
||||
DataQueryResponse,
|
||||
LogRowContextOptions,
|
||||
EventBus,
|
||||
ExplorePanelsState,
|
||||
TimeRange,
|
||||
LogsDedupStrategy,
|
||||
LogsSortOrder,
|
||||
CoreApp,
|
||||
LogsDedupDescription,
|
||||
rangeUtil,
|
||||
ExploreLogsPanelState,
|
||||
DataFrame,
|
||||
DataHoverClearEvent,
|
||||
DataHoverEvent,
|
||||
serializeStateToUrlParam,
|
||||
urlUtil,
|
||||
DataQueryResponse,
|
||||
EventBus,
|
||||
ExploreLogsPanelState,
|
||||
ExplorePanelsState,
|
||||
FieldConfigSource,
|
||||
GrafanaTheme2,
|
||||
LoadingState,
|
||||
LogLevel,
|
||||
LogRowContextOptions,
|
||||
LogRowModel,
|
||||
LogsDedupDescription,
|
||||
LogsDedupStrategy,
|
||||
LogsMetaItem,
|
||||
LogsSortOrder,
|
||||
PanelData,
|
||||
rangeUtil,
|
||||
RawTimeRange,
|
||||
serializeStateToUrlParam,
|
||||
shallowCompare,
|
||||
SplitOpen,
|
||||
TimeRange,
|
||||
TimeZone,
|
||||
urlUtil,
|
||||
} from '@grafana/data';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { t, Trans } from '@grafana/i18n';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { DataQuery, DataTopic } from '@grafana/schema';
|
||||
import {
|
||||
@@ -47,6 +49,7 @@ import {
|
||||
Themeable2,
|
||||
withTheme2,
|
||||
} from '@grafana/ui';
|
||||
import { replaceVariables } from '@grafana-plugins/loki/querybuilder/parsingUtils';
|
||||
import store from 'app/core/store';
|
||||
import { createAndCopyShortLink, getLogsPermalinkRange } from 'app/core/utils/shortLinks';
|
||||
import { ControlledLogRows } from 'app/features/logs/components/ControlledLogRows';
|
||||
@@ -56,15 +59,17 @@ import { LogRowContextModal } from 'app/features/logs/components/log-context/Log
|
||||
import { LogLineContext } from 'app/features/logs/components/panel/LogLineContext';
|
||||
import { LogList, LogListOptions } from 'app/features/logs/components/panel/LogList';
|
||||
import { isDedupStrategy, isLogsSortOrder } from 'app/features/logs/components/panel/LogListContext';
|
||||
import { LogLevelColor, dedupLogRows } from 'app/features/logs/logsModel';
|
||||
import { dedupLogRows, LogLevelColor } from 'app/features/logs/logsModel';
|
||||
import { getLogLevelFromKey, getLogLevelInfo } from 'app/features/logs/utils';
|
||||
import { LokiQueryDirection } from 'app/plugins/datasource/loki/dataquery.gen';
|
||||
import { isLokiQuery } from 'app/plugins/datasource/loki/queryUtils';
|
||||
import { GetFieldLinksFn } from 'app/plugins/panel/logs/types';
|
||||
import { Options } from 'app/plugins/panel/logstable/panelcfg.gen';
|
||||
import { getState } from 'app/store/store';
|
||||
import { ExploreItemState } from 'app/types/explore';
|
||||
import { useDispatch } from 'app/types/store';
|
||||
|
||||
import { LogsTable } from '../../../plugins/panel/logstable/LogsTable';
|
||||
import {
|
||||
contentOutlineTrackPinAdded,
|
||||
contentOutlineTrackPinClicked,
|
||||
@@ -80,7 +85,7 @@ import { changeQueries, runQueries } from '../state/query';
|
||||
import { LogsFeedback } from './LogsFeedback';
|
||||
import { LogsMetaRow } from './LogsMetaRow';
|
||||
import LogsNavigation from './LogsNavigation';
|
||||
import { LogsTableWrap, getLogsTableHeight } from './LogsTableWrap';
|
||||
import { getLogsTableHeight, LogsTableWrap } from './LogsTableWrap';
|
||||
import { LogsVolumePanelList } from './LogsVolumePanelList';
|
||||
import { SETTING_KEY_ROOT, SETTINGS_KEYS, visualisationTypeKey } from './utils/logs';
|
||||
import { getExploreBaseUrl } from './utils/url';
|
||||
@@ -127,8 +132,9 @@ interface Props extends Themeable2 {
|
||||
range: TimeRange;
|
||||
onClickFilterString?: (value: string, refId?: string) => void;
|
||||
onClickFilterOutString?: (value: string, refId?: string) => void;
|
||||
loadMoreLogs?(range: AbsoluteTimeRange): void;
|
||||
onPinLineCallback?: () => void;
|
||||
|
||||
loadMoreLogs?(range: AbsoluteTimeRange): void;
|
||||
}
|
||||
|
||||
export type LogsVisualisationType = 'table' | 'logs';
|
||||
@@ -764,6 +770,14 @@ const UnthemedLogs: React.FunctionComponent<Props> = (props: Props) => {
|
||||
setFilterLevels(levels.map((level) => getLogLevelFromKey(level)));
|
||||
}, []);
|
||||
|
||||
// @todo ff
|
||||
const enableNewLogsTable = true;
|
||||
const panelData: PanelData = {
|
||||
state: loading ? LoadingState.Loading : LoadingState.Done,
|
||||
series: props.logsFrames ?? [],
|
||||
timeRange: props.range,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{(!config.featureToggles.newLogsPanel || !config.featureToggles.newLogContext) && getRowContext && contextRow && (
|
||||
@@ -989,24 +1003,55 @@ const UnthemedLogs: React.FunctionComponent<Props> = (props: Props) => {
|
||||
<div className={cx(styles.logsSection, visualisationType === 'table' ? styles.logsTable : undefined)}>
|
||||
{!config.featureToggles.logsPanelControls && visualisationType === 'table' && hasData && (
|
||||
<div className={styles.logRows} data-testid="logRowsTable">
|
||||
{/* Width should be full width minus logs navigation and padding */}
|
||||
<LogsTableWrap
|
||||
logsSortOrder={logsSortOrder}
|
||||
range={props.range}
|
||||
splitOpen={splitOpen}
|
||||
timeZone={timeZone}
|
||||
width={width - 80}
|
||||
logsFrames={props.logsFrames ?? []}
|
||||
onClickFilterLabel={onClickFilterLabel}
|
||||
onClickFilterOutLabel={onClickFilterOutLabel}
|
||||
panelState={panelState?.logs}
|
||||
updatePanelState={updatePanelState}
|
||||
datasourceType={props.datasourceType}
|
||||
displayedFields={displayedFields}
|
||||
exploreId={props.exploreId}
|
||||
absoluteRange={props.absoluteRange}
|
||||
logRows={props.logRows}
|
||||
/>
|
||||
{/* @todo add flag*/}
|
||||
{enableNewLogsTable && (
|
||||
<LogsTable
|
||||
id={0}
|
||||
data={panelData}
|
||||
timeRange={props.range}
|
||||
timeZone={timeZone}
|
||||
options={{}}
|
||||
transparent={false}
|
||||
width={width - 80}
|
||||
height={tableHeight}
|
||||
fieldConfig={{
|
||||
defaults: {},
|
||||
overrides: [],
|
||||
}}
|
||||
renderCounter={0}
|
||||
title={''}
|
||||
eventBus={props.eventBus}
|
||||
onOptionsChange={function (options: Options): void {
|
||||
console.log('onOptionsChange NOT IMP:', options);
|
||||
// throw new Error('Function not implemented.');
|
||||
}}
|
||||
onFieldConfigChange={function (config: FieldConfigSource): void {
|
||||
console.log('onFieldConfigChange NOT IMP:', config);
|
||||
}}
|
||||
replaceVariables={replaceVariables}
|
||||
onChangeTimeRange={onChangeTime}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!enableNewLogsTable && (
|
||||
<LogsTableWrap
|
||||
logsSortOrder={logsSortOrder}
|
||||
range={props.range}
|
||||
splitOpen={splitOpen}
|
||||
timeZone={timeZone}
|
||||
width={width - 80}
|
||||
logsFrames={props.logsFrames ?? []}
|
||||
onClickFilterLabel={onClickFilterLabel}
|
||||
onClickFilterOutLabel={onClickFilterOutLabel}
|
||||
panelState={panelState?.logs}
|
||||
updatePanelState={updatePanelState}
|
||||
datasourceType={props.datasourceType}
|
||||
displayedFields={displayedFields}
|
||||
exploreId={props.exploreId}
|
||||
absoluteRange={props.absoluteRange}
|
||||
logRows={props.logRows}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{(!config.featureToggles.newLogsPanel || visualisationType === 'table') &&
|
||||
@@ -1014,6 +1059,10 @@ const UnthemedLogs: React.FunctionComponent<Props> = (props: Props) => {
|
||||
hasData && (
|
||||
<div className={styles.controlledLogRowsWrapper} data-testid="logRows">
|
||||
<ControlledLogRows
|
||||
fieldConfig={{
|
||||
defaults: {},
|
||||
overrides: [],
|
||||
}}
|
||||
ref={logsContainerRef}
|
||||
logsTableFrames={props.logsFrames}
|
||||
width={width}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { useEffect, useMemo, useRef, forwardRef, useImperativeHandle, useCallback } from 'react';
|
||||
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
||||
|
||||
import {
|
||||
AbsoluteTimeRange,
|
||||
@@ -7,17 +7,23 @@ import {
|
||||
DataFrame,
|
||||
EventBusSrv,
|
||||
ExploreLogsPanelState,
|
||||
FieldConfigSource,
|
||||
LoadingState,
|
||||
LogLevel,
|
||||
LogRowModel,
|
||||
LogsMetaItem,
|
||||
LogsSortOrder,
|
||||
PanelData,
|
||||
SplitOpen,
|
||||
TimeRange,
|
||||
} from '@grafana/data';
|
||||
import { getAppEvents, getTemplateSrv } from '@grafana/runtime';
|
||||
import { PanelContextProvider } from '@grafana/ui';
|
||||
import { Options } from 'app/plugins/panel/logstable/panelcfg.gen';
|
||||
|
||||
import { LogsTable } from '../../../plugins/panel/logstable/LogsTable';
|
||||
import { LogsVisualisationType } from '../../explore/Logs/Logs';
|
||||
|
||||
import { ControlledLogsTable } from './ControlledLogsTable';
|
||||
import { InfiniteScroll } from './InfiniteScroll';
|
||||
import { LogRows, Props } from './LogRows';
|
||||
import { LogListOptions } from './panel/LogList';
|
||||
@@ -25,6 +31,12 @@ import { LogListContextProvider, useLogListContext } from './panel/LogListContex
|
||||
import { LogListControls } from './panel/LogListControls';
|
||||
import { ScrollToLogsEvent } from './panel/virtualization';
|
||||
|
||||
// @todo
|
||||
export const FILTER_FOR_OPERATOR = '=';
|
||||
export const FILTER_OUT_OPERATOR = '!=';
|
||||
export type AdHocFilterOperator = typeof FILTER_FOR_OPERATOR | typeof FILTER_OUT_OPERATOR;
|
||||
export type AdHocFilterItem = { key: string; value: string; operator: AdHocFilterOperator };
|
||||
|
||||
export interface ControlledLogRowsProps extends Omit<Props, 'scrollElement'> {
|
||||
loading: boolean;
|
||||
logsMeta?: LogsMetaItem[];
|
||||
@@ -33,6 +45,7 @@ export interface ControlledLogRowsProps extends Omit<Props, 'scrollElement'> {
|
||||
onLogOptionsChange?: (option: LogListOptions, value: string | boolean | string[]) => void;
|
||||
range: TimeRange;
|
||||
filterLevels?: LogLevel[];
|
||||
fieldConfig: FieldConfigSource;
|
||||
|
||||
/** Props added for Table **/
|
||||
visualisationType: LogsVisualisationType;
|
||||
@@ -74,10 +87,35 @@ export const ControlledLogRows = forwardRef<HTMLDivElement | null, ControlledLog
|
||||
prettifyLogMessage,
|
||||
onLogOptionsChange,
|
||||
wrapLogMessage,
|
||||
fieldConfig,
|
||||
...rest
|
||||
}: ControlledLogRowsProps,
|
||||
ref
|
||||
) => {
|
||||
const dataFrames = rest.logsTableFrames ?? [];
|
||||
const panelData: PanelData = {
|
||||
state: rest.loading ? LoadingState.Loading : LoadingState.Done,
|
||||
series: dataFrames,
|
||||
timeRange: rest.timeRange,
|
||||
};
|
||||
|
||||
const eventBus = getAppEvents();
|
||||
|
||||
const onCellFilterAdded = (filter: AdHocFilterItem) => {
|
||||
const { value, key, operator } = filter;
|
||||
const { onClickFilterLabel, onClickFilterOutLabel } = rest;
|
||||
if (!onClickFilterLabel || !onClickFilterOutLabel) {
|
||||
return;
|
||||
}
|
||||
if (operator === FILTER_FOR_OPERATOR) {
|
||||
onClickFilterLabel(key, value, dataFrames[0]);
|
||||
}
|
||||
|
||||
if (operator === FILTER_OUT_OPERATOR) {
|
||||
onClickFilterOutLabel(key, value, dataFrames[0]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<LogListContextProvider
|
||||
app={rest.app || CoreApp.Unknown}
|
||||
@@ -97,9 +135,46 @@ export const ControlledLogRows = forwardRef<HTMLDivElement | null, ControlledLog
|
||||
wrapLogMessage={wrapLogMessage}
|
||||
>
|
||||
{rest.visualisationType === 'logs' && (
|
||||
<LogRowsComponent ref={ref} {...rest} deduplicatedRows={deduplicatedRows} />
|
||||
<LogRowsComponent
|
||||
ref={ref}
|
||||
{...rest}
|
||||
deduplicatedRows={deduplicatedRows}
|
||||
fieldConfig={{ defaults: {}, overrides: [] }}
|
||||
/>
|
||||
)}
|
||||
{rest.visualisationType === 'table' && rest.updatePanelState && (
|
||||
<PanelContextProvider
|
||||
value={{
|
||||
eventsScope: 'explore',
|
||||
eventBus: eventBus ?? new EventBusSrv(),
|
||||
onAddAdHocFilter: onCellFilterAdded,
|
||||
}}
|
||||
>
|
||||
<LogsTable
|
||||
id={0}
|
||||
width={rest.width ?? 0}
|
||||
data={panelData}
|
||||
options={{}}
|
||||
transparent={false}
|
||||
height={800}
|
||||
fieldConfig={fieldConfig}
|
||||
renderCounter={0}
|
||||
title={''}
|
||||
eventBus={eventBus}
|
||||
onOptionsChange={function (options: Options): void {
|
||||
console.log('onOptionsChange not implemented');
|
||||
}}
|
||||
onFieldConfigChange={function (config: FieldConfigSource): void {
|
||||
console.log('onFieldConfigChange not implemented');
|
||||
}}
|
||||
replaceVariables={getTemplateSrv().replace.bind(getTemplateSrv())}
|
||||
onChangeTimeRange={function (timeRange: AbsoluteTimeRange): void {
|
||||
console.log('onChangeTimeRange not implemented');
|
||||
}}
|
||||
{...rest}
|
||||
/>
|
||||
</PanelContextProvider>
|
||||
)}
|
||||
{rest.visualisationType === 'table' && rest.updatePanelState && <ControlledLogsTable {...rest} />}
|
||||
</LogListContextProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
DataFrame,
|
||||
LogRowContextOptions,
|
||||
TimeRange,
|
||||
FieldConfigSource,
|
||||
} from '@grafana/data';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { DataQuery } from '@grafana/schema';
|
||||
@@ -73,6 +74,7 @@ export interface Props {
|
||||
logRowMenuIconsAfter?: ReactNode[];
|
||||
scrollElement: HTMLDivElement | null;
|
||||
renderPreview?: boolean;
|
||||
fieldConfig?: FieldConfigSource;
|
||||
}
|
||||
|
||||
export type PopoverStateType = {
|
||||
|
||||
@@ -653,6 +653,7 @@ export const LogsPanel = ({
|
||||
sortOrder={sortOrder}
|
||||
>
|
||||
<LogRows
|
||||
fieldConfig={fieldConfig}
|
||||
scrollElement={scrollElement}
|
||||
scrollIntoView={scrollIntoView}
|
||||
permalinkedRowId={getLogsPanelState()?.logs?.id ?? undefined}
|
||||
@@ -705,6 +706,7 @@ export const LogsPanel = ({
|
||||
ref={(scrollElement: HTMLDivElement | null) => {
|
||||
setScrollElement(scrollElement);
|
||||
}}
|
||||
fieldConfig={fieldConfig}
|
||||
visualisationType="logs"
|
||||
loading={infiniteScrolling}
|
||||
loadMoreLogs={enableInfiniteScrolling ? loadMoreLogs : undefined}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { lastValueFrom } from 'rxjs';
|
||||
import {
|
||||
applyFieldOverrides,
|
||||
DataFrame,
|
||||
Field,
|
||||
FieldConfigSource,
|
||||
GrafanaTheme2,
|
||||
PanelProps,
|
||||
@@ -25,13 +26,7 @@ import {
|
||||
parseLogsFrame,
|
||||
} from '../../../features/logs/logsFrame';
|
||||
import { isSetDisplayedFields } from '../logs/types';
|
||||
import {
|
||||
AdHocFilterItem,
|
||||
FILTER_FOR_OPERATOR,
|
||||
FILTER_OUT_OPERATOR,
|
||||
TableFilterActionCallback,
|
||||
TablePanel,
|
||||
} from '../table/TablePanel';
|
||||
import { TablePanel } from '../table/TablePanel';
|
||||
import type { Options as TableOptions } from '../table/panelcfg.gen';
|
||||
|
||||
import type { Options as LogsTableOptions } from './panelcfg.gen';
|
||||
@@ -125,39 +120,11 @@ export const LogsTable = ({
|
||||
|
||||
const handleTableOnFieldConfigChange = useCallback(
|
||||
(fieldConfig: FieldConfigSource) => {
|
||||
console.log('onTableOnFieldConfigChange', fieldConfig);
|
||||
onFieldConfigChange(fieldConfig);
|
||||
},
|
||||
[onFieldConfigChange]
|
||||
);
|
||||
|
||||
const handleOnCellFilterAdded: TableFilterActionCallback = (filter: AdHocFilterItem) => {
|
||||
const { value, key, operator } = filter;
|
||||
if (operator === FILTER_FOR_OPERATOR) {
|
||||
onClickFilterLabel(key, value);
|
||||
}
|
||||
|
||||
if (operator === FILTER_OUT_OPERATOR) {
|
||||
onClickFilterOutLabel(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @todo
|
||||
* Used by Logs details.
|
||||
*/
|
||||
const onClickFilterLabel = (key: string, value: string | number, frame?: DataFrame) => {
|
||||
console.log('onClickFilterLabel', key, value, frame);
|
||||
};
|
||||
|
||||
/**
|
||||
* @todo
|
||||
* Used by Logs details.
|
||||
*/
|
||||
const onClickFilterOutLabel = (key: string, value: string | number, frame?: DataFrame) => {
|
||||
console.log('onClickFilterOutLabel', key, value, frame);
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract fields transform
|
||||
*/
|
||||
@@ -169,18 +136,32 @@ export const LogsTable = ({
|
||||
};
|
||||
|
||||
extractFields().then((frame) => {
|
||||
setExtractedFrame(
|
||||
applyFieldOverrides({
|
||||
data: frame,
|
||||
fieldConfig,
|
||||
replaceVariables: getTemplateSrv().replace.bind(getTemplateSrv()),
|
||||
theme: config.theme2,
|
||||
timeZone: timeZone,
|
||||
dataLinkPostProcessor: dataLinksContext.dataLinkPostProcessor,
|
||||
})
|
||||
);
|
||||
const extractedFrames = applyFieldOverrides({
|
||||
data: frame,
|
||||
fieldConfig: fieldConfig,
|
||||
replaceVariables: replaceVariables ?? getTemplateSrv().replace.bind(getTemplateSrv()),
|
||||
theme: config.theme2,
|
||||
timeZone: timeZone,
|
||||
dataLinkPostProcessor: dataLinksContext.dataLinkPostProcessor,
|
||||
});
|
||||
|
||||
for (let frameIndex = 0; frameIndex < extractedFrames.length; frameIndex++) {
|
||||
const frame = extractedFrames[frameIndex];
|
||||
for (const [, field] of frame.fields.entries()) {
|
||||
field.config = {
|
||||
...field.config,
|
||||
filterable: field.config?.filterable ?? doesFieldSupportAdHocFiltering(field),
|
||||
custom: {
|
||||
...field.config.custom,
|
||||
inspect: field.config?.custom?.inspect ?? true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
setExtractedFrame(extractedFrames);
|
||||
});
|
||||
}, [dataLinksContext.dataLinkPostProcessor, fieldConfig, timeZone, unTransformedDataFrame]);
|
||||
}, [dataLinksContext.dataLinkPostProcessor, fieldConfig, replaceVariables, timeZone, unTransformedDataFrame]);
|
||||
|
||||
/**
|
||||
* Organize fields transform
|
||||
@@ -267,7 +248,6 @@ export const LogsTable = ({
|
||||
onFieldConfigChange={handleTableOnFieldConfigChange}
|
||||
replaceVariables={replaceVariables}
|
||||
onChangeTimeRange={onChangeTimeRange}
|
||||
onCellFilterAdded={handleOnCellFilterAdded}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -293,6 +273,10 @@ function displayedFieldsToColumns(displayedFields: string[], logsFrame: LogsFram
|
||||
return columns;
|
||||
}
|
||||
|
||||
function doesFieldSupportAdHocFiltering(field: Field): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2, sidebarWidth: number, height: number, width: number) => {
|
||||
return {
|
||||
tableWrapper: css({
|
||||
|
||||
@@ -24,16 +24,7 @@ import { getActions } from '../../../features/actions/utils';
|
||||
import { hasDeprecatedParentRowIndex, migrateFromParentRowIndexToNestedFrames } from './migrations';
|
||||
import { Options } from './panelcfg.gen';
|
||||
|
||||
/** @todo get yelled at by dataviz */
|
||||
export const FILTER_FOR_OPERATOR = '=';
|
||||
export const FILTER_OUT_OPERATOR = '!=';
|
||||
export type AdHocFilterOperator = typeof FILTER_FOR_OPERATOR | typeof FILTER_OUT_OPERATOR;
|
||||
export type AdHocFilterItem = { key: string; value: string; operator: AdHocFilterOperator };
|
||||
export type TableFilterActionCallback = (item: AdHocFilterItem) => void;
|
||||
|
||||
interface Props extends PanelProps<Options> {
|
||||
onCellFilterAdded?: TableFilterActionCallback;
|
||||
}
|
||||
interface Props extends PanelProps<Options> {}
|
||||
|
||||
export function TablePanel(props: Props) {
|
||||
const { data, height, width, options, fieldConfig, id, timeRange, replaceVariables, transparent } = props;
|
||||
@@ -86,7 +77,7 @@ export function TablePanel(props: Props) {
|
||||
initialSortBy={options.sortBy}
|
||||
onSortByChange={(sortBy) => onSortByChange(sortBy, props)}
|
||||
onColumnResize={(displayName, resizedWidth) => onColumnResize(displayName, resizedWidth, props)}
|
||||
onCellFilterAdded={props.onCellFilterAdded ?? panelContext.onAddAdHocFilter}
|
||||
onCellFilterAdded={panelContext.onAddAdHocFilter}
|
||||
frozenColumns={options.frozenColumns?.left}
|
||||
enablePagination={options.enablePagination}
|
||||
cellHeight={options.cellHeight}
|
||||
|
||||
Reference in New Issue
Block a user