mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 10:50:37 -06:00
Chore: Remove several instances of non-strict null usage (#20563)
This commit is contained in:
parent
665079dc8c
commit
514f2beafc
@ -18,8 +18,8 @@ export interface LocationUpdate {
|
|||||||
replace?: boolean;
|
replace?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UrlQueryValue = string | number | boolean | string[] | number[] | boolean[];
|
export type UrlQueryValue = string | number | boolean | string[] | number[] | boolean[] | undefined;
|
||||||
export type UrlQueryMap = { [s: string]: UrlQueryValue };
|
export type UrlQueryMap = Record<string, UrlQueryValue>;
|
||||||
|
|
||||||
export interface LocationSrv {
|
export interface LocationSrv {
|
||||||
update(options: LocationUpdate): void;
|
update(options: LocationUpdate): void;
|
||||||
|
@ -83,7 +83,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isOpen: boolean;
|
isOpen?: boolean;
|
||||||
label: string;
|
label: string;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
collapsible?: boolean;
|
collapsible?: boolean;
|
||||||
|
@ -14,7 +14,7 @@ export interface GraphProps {
|
|||||||
children?: JSX.Element | JSX.Element[];
|
children?: JSX.Element | JSX.Element[];
|
||||||
series: GraphSeriesXY[];
|
series: GraphSeriesXY[];
|
||||||
timeRange: TimeRange; // NOTE: we should aim to make `time` a property of the axis, not force it for all graphs
|
timeRange: TimeRange; // NOTE: we should aim to make `time` a property of the axis, not force it for all graphs
|
||||||
timeZone: TimeZone; // NOTE: we should aim to make `time` a property of the axis, not force it for all graphs
|
timeZone?: TimeZone; // NOTE: we should aim to make `time` a property of the axis, not force it for all graphs
|
||||||
showLines?: boolean;
|
showLines?: boolean;
|
||||||
showPoints?: boolean;
|
showPoints?: boolean;
|
||||||
showBars?: boolean;
|
showBars?: boolean;
|
||||||
@ -246,7 +246,7 @@ export class Graph extends PureComponent<GraphProps, GraphState> {
|
|||||||
label: 'Datetime',
|
label: 'Datetime',
|
||||||
ticks: ticks,
|
ticks: ticks,
|
||||||
timeformat: timeFormat(ticks, min, max),
|
timeformat: timeFormat(ticks, min, max),
|
||||||
timezone: timeZone ? timeZone : DefaultTimeZone,
|
timezone: timeZone ?? DefaultTimeZone,
|
||||||
},
|
},
|
||||||
yaxes,
|
yaxes,
|
||||||
grid: {
|
grid: {
|
||||||
|
@ -16,7 +16,7 @@ export interface Props extends Themeable {
|
|||||||
logRows?: LogRowModel[];
|
logRows?: LogRowModel[];
|
||||||
deduplicatedRows?: LogRowModel[];
|
deduplicatedRows?: LogRowModel[];
|
||||||
dedupStrategy: LogsDedupStrategy;
|
dedupStrategy: LogsDedupStrategy;
|
||||||
highlighterExpressions: string[];
|
highlighterExpressions?: string[];
|
||||||
showTime: boolean;
|
showTime: boolean;
|
||||||
timeZone: TimeZone;
|
timeZone: TimeZone;
|
||||||
rowLimit?: number;
|
rowLimit?: number;
|
||||||
|
@ -37,7 +37,7 @@ export interface Props {
|
|||||||
export class RefreshPickerBase extends PureComponent<Props> {
|
export class RefreshPickerBase extends PureComponent<Props> {
|
||||||
static offOption = { label: 'Off', value: '' };
|
static offOption = { label: 'Off', value: '' };
|
||||||
static liveOption = { label: 'Live', value: 'LIVE' };
|
static liveOption = { label: 'Live', value: 'LIVE' };
|
||||||
static isLive = (refreshInterval: string): boolean => refreshInterval === RefreshPicker.liveOption.value;
|
static isLive = (refreshInterval?: string): boolean => refreshInterval === RefreshPicker.liveOption.value;
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -42,7 +42,7 @@ export const LogLevelColor = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const isoDateRegexp = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d[,\.]\d+([+-][0-2]\d:[0-5]\d|Z)/g;
|
const isoDateRegexp = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d[,\.]\d+([+-][0-2]\d:[0-5]\d|Z)/g;
|
||||||
function isDuplicateRow(row: LogRowModel, other: LogRowModel, strategy: LogsDedupStrategy): boolean {
|
function isDuplicateRow(row: LogRowModel, other: LogRowModel, strategy?: LogsDedupStrategy): boolean {
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
case LogsDedupStrategy.exact:
|
case LogsDedupStrategy.exact:
|
||||||
// Exact still strips dates
|
// Exact still strips dates
|
||||||
@ -59,7 +59,7 @@ function isDuplicateRow(row: LogRowModel, other: LogRowModel, strategy: LogsDedu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dedupLogRows(rows: LogRowModel[], strategy: LogsDedupStrategy): LogRowModel[] {
|
export function dedupLogRows(rows: LogRowModel[], strategy?: LogsDedupStrategy): LogRowModel[] {
|
||||||
if (strategy === LogsDedupStrategy.none) {
|
if (strategy === LogsDedupStrategy.none) {
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ export function dedupLogRows(rows: LogRowModel[], strategy: LogsDedupStrategy):
|
|||||||
const rowCopy = { ...row };
|
const rowCopy = { ...row };
|
||||||
const previous = result[result.length - 1];
|
const previous = result[result.length - 1];
|
||||||
if (index > 0 && isDuplicateRow(row, previous, strategy)) {
|
if (index > 0 && isDuplicateRow(row, previous, strategy)) {
|
||||||
previous.duplicates++;
|
previous.duplicates!++;
|
||||||
} else {
|
} else {
|
||||||
rowCopy.duplicates = 0;
|
rowCopy.duplicates = 0;
|
||||||
result.push(rowCopy);
|
result.push(rowCopy);
|
||||||
|
@ -202,20 +202,20 @@ describe('hasNonEmptyQuery', () => {
|
|||||||
|
|
||||||
describe('hasRefId', () => {
|
describe('hasRefId', () => {
|
||||||
describe('when called with a null value', () => {
|
describe('when called with a null value', () => {
|
||||||
it('then it should return null', () => {
|
it('then it should return undefined', () => {
|
||||||
const input: any = null;
|
const input: any = null;
|
||||||
const result = getValueWithRefId(input);
|
const result = getValueWithRefId(input);
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when called with a non object value', () => {
|
describe('when called with a non object value', () => {
|
||||||
it('then it should return null', () => {
|
it('then it should return undefined', () => {
|
||||||
const input = 123;
|
const input = 123;
|
||||||
const result = getValueWithRefId(input);
|
const result = getValueWithRefId(input);
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -249,11 +249,11 @@ describe('hasRefId', () => {
|
|||||||
|
|
||||||
describe('getFirstQueryErrorWithoutRefId', () => {
|
describe('getFirstQueryErrorWithoutRefId', () => {
|
||||||
describe('when called with a null value', () => {
|
describe('when called with a null value', () => {
|
||||||
it('then it should return null', () => {
|
it('then it should return undefined', () => {
|
||||||
const errors: DataQueryError[] = null;
|
const errors: DataQueryError[] = null;
|
||||||
const result = getFirstQueryErrorWithoutRefId(errors);
|
const result = getFirstQueryErrorWithoutRefId(errors);
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -418,13 +418,9 @@ export const getTimeRangeFromUrl = (range: RawTimeRange, timeZone: TimeZone): Ti
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getValueWithRefId = (value: any): any | null => {
|
export const getValueWithRefId = (value?: any): any => {
|
||||||
if (!value) {
|
if (!value || typeof value !== 'object') {
|
||||||
return null;
|
return undefined;
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof value !== 'object') {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.refId) {
|
if (value.refId) {
|
||||||
@ -440,12 +436,12 @@ export const getValueWithRefId = (value: any): any | null => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getFirstQueryErrorWithoutRefId = (errors: DataQueryError[]) => {
|
export const getFirstQueryErrorWithoutRefId = (errors?: DataQueryError[]) => {
|
||||||
if (!errors) {
|
if (!errors) {
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.filter(error => (error && error.refId ? false : true))[0];
|
return errors.filter(error => (error && error.refId ? false : true))[0];
|
||||||
@ -503,7 +499,7 @@ export enum SortOrder {
|
|||||||
Ascending = 'Ascending',
|
Ascending = 'Ascending',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const refreshIntervalToSortOrder = (refreshInterval: string) =>
|
export const refreshIntervalToSortOrder = (refreshInterval?: string) =>
|
||||||
RefreshPicker.isLive(refreshInterval) ? SortOrder.Ascending : SortOrder.Descending;
|
RefreshPicker.isLive(refreshInterval) ? SortOrder.Ascending : SortOrder.Descending;
|
||||||
|
|
||||||
export const sortLogsResult = (logsResult: LogsModel, sortOrder: SortOrder): LogsModel => {
|
export const sortLogsResult = (logsResult: LogsModel, sortOrder: SortOrder): LogsModel => {
|
||||||
|
@ -36,6 +36,11 @@ export const AdHocFilter: React.FunctionComponent<Props> = props => {
|
|||||||
|
|
||||||
const onChange = (changeType: ChangeType) => (item: SelectableValue<string>) => {
|
const onChange = (changeType: ChangeType) => (item: SelectableValue<string>) => {
|
||||||
const { onKeyChanged, onValueChanged, onOperatorChanged } = props;
|
const { onKeyChanged, onValueChanged, onOperatorChanged } = props;
|
||||||
|
|
||||||
|
if (!item.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (changeType) {
|
switch (changeType) {
|
||||||
case ChangeType.Key:
|
case ChangeType.Key:
|
||||||
onKeyChanged(item.value);
|
onKeyChanged(item.value);
|
||||||
@ -54,13 +59,13 @@ export const AdHocFilter: React.FunctionComponent<Props> = props => {
|
|||||||
const { keys, initialKey, keysPlaceHolder, initialOperator, values, initialValue, valuesPlaceHolder } = props;
|
const { keys, initialKey, keysPlaceHolder, initialOperator, values, initialValue, valuesPlaceHolder } = props;
|
||||||
const operators = ['=', '!='];
|
const operators = ['=', '!='];
|
||||||
const keysAsOptions = keys ? keys.map(stringToOption) : [];
|
const keysAsOptions = keys ? keys.map(stringToOption) : [];
|
||||||
const selectedKey = initialKey ? keysAsOptions.filter(option => option.value === initialKey) : null;
|
const selectedKey = initialKey ? keysAsOptions.filter(option => option.value === initialKey) : undefined;
|
||||||
const valuesAsOptions = values ? values.map(stringToOption) : [];
|
const valuesAsOptions = values ? values.map(stringToOption) : [];
|
||||||
const selectedValue = initialValue ? valuesAsOptions.filter(option => option.value === initialValue) : null;
|
const selectedValue = initialValue ? valuesAsOptions.filter(option => option.value === initialValue) : undefined;
|
||||||
const operatorsAsOptions = operators.map(stringToOption);
|
const operatorsAsOptions = operators.map(stringToOption);
|
||||||
const selectedOperator = initialOperator
|
const selectedOperator = initialOperator
|
||||||
? operatorsAsOptions.filter(option => option.value === initialOperator)
|
? operatorsAsOptions.filter(option => option.value === initialOperator)
|
||||||
: null;
|
: undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx([styles.keyValueContainer])}>
|
<div className={cx([styles.keyValueContainer])}>
|
||||||
|
@ -174,11 +174,11 @@ describe('AdHocFilterField', () => {
|
|||||||
const { instance } = setup();
|
const { instance } = setup();
|
||||||
const pairs: KeyValuePair[] = [];
|
const pairs: KeyValuePair[] = [];
|
||||||
const index = 0;
|
const index = 0;
|
||||||
const key: string = undefined;
|
const key: undefined = undefined;
|
||||||
const keys: string[] = ['key 1', 'key 2'];
|
const keys: string[] = ['key 1', 'key 2'];
|
||||||
const value: string = undefined;
|
const value: undefined = undefined;
|
||||||
const values: string[] = undefined;
|
const values: undefined = undefined;
|
||||||
const operator: string = undefined;
|
const operator: undefined = undefined;
|
||||||
|
|
||||||
const result = instance.updatePairs(pairs, index, { key, keys, value, values, operator });
|
const result = instance.updatePairs(pairs, index, { key, keys, value, values, operator });
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ export class AdHocFilterField<
|
|||||||
return allPairs;
|
return allPairs;
|
||||||
}
|
}
|
||||||
return allPairs.concat(pair);
|
return allPairs.concat(pair);
|
||||||
}, []);
|
}, [] as KeyValuePair[]);
|
||||||
|
|
||||||
this.setState({ pairs });
|
this.setState({ pairs });
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ import { FadeIn } from 'app/core/components/Animations/FadeIn';
|
|||||||
import { getFirstQueryErrorWithoutRefId, getValueWithRefId } from 'app/core/utils/explore';
|
import { getFirstQueryErrorWithoutRefId, getValueWithRefId } from 'app/core/utils/explore';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
queryErrors: DataQueryError[];
|
queryErrors?: DataQueryError[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ErrorContainer: FunctionComponent<Props> = props => {
|
export const ErrorContainer: FunctionComponent<Props> = props => {
|
||||||
|
@ -203,9 +203,10 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
|
|
||||||
onModifyQueries = (action: any, index?: number) => {
|
onModifyQueries = (action: any, index?: number) => {
|
||||||
const { datasourceInstance } = this.props;
|
const { datasourceInstance } = this.props;
|
||||||
if (datasourceInstance && datasourceInstance.modifyQuery) {
|
if (datasourceInstance?.modifyQuery) {
|
||||||
const modifier = (queries: DataQuery, modification: any) => datasourceInstance.modifyQuery(queries, modification);
|
const modifier = (queries: DataQuery, modification: any) =>
|
||||||
this.props.modifyQueries(this.props.exploreId, action, index, modifier);
|
datasourceInstance.modifyQuery!(queries, modification);
|
||||||
|
this.props.modifyQueries(this.props.exploreId, action, modifier, index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -277,7 +278,7 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
{datasourceInstance && (
|
{datasourceInstance && (
|
||||||
<div className="explore-container">
|
<div className="explore-container">
|
||||||
<QueryRows exploreEvents={this.exploreEvents} exploreId={exploreId} queryKeys={queryKeys} />
|
<QueryRows exploreEvents={this.exploreEvents} exploreId={exploreId} queryKeys={queryKeys} />
|
||||||
<ErrorContainer queryErrors={[queryResponse.error]} />
|
<ErrorContainer queryErrors={queryResponse.error ? [queryResponse.error] : undefined} />
|
||||||
<AutoSizer onResize={this.onResize} disableHeight>
|
<AutoSizer onResize={this.onResize} disableHeight>
|
||||||
{({ width }) => {
|
{({ width }) => {
|
||||||
if (width === 0) {
|
if (width === 0) {
|
||||||
@ -287,7 +288,7 @@ export class Explore extends React.PureComponent<ExploreProps> {
|
|||||||
return (
|
return (
|
||||||
<main className={`m-t-2 ${styles.logsMain}`} style={{ width }}>
|
<main className={`m-t-2 ${styles.logsMain}`} style={{ width }}>
|
||||||
<ErrorBoundaryAlert>
|
<ErrorBoundaryAlert>
|
||||||
{showingStartPage && (
|
{showingStartPage && StartPage && (
|
||||||
<div className="grafana-info-box grafana-info-box--max-lg">
|
<div className="grafana-info-box grafana-info-box--max-lg">
|
||||||
<StartPage
|
<StartPage
|
||||||
onClickExample={this.onClickExample}
|
onClickExample={this.onClickExample}
|
||||||
@ -377,7 +378,7 @@ function mapStateToProps(state: StoreState, { exploreId }: ExploreProps): Partia
|
|||||||
const initialQueries: DataQuery[] = ensureQueriesMemoized(queries);
|
const initialQueries: DataQuery[] = ensureQueriesMemoized(queries);
|
||||||
const initialRange = urlRange ? getTimeRangeFromUrlMemoized(urlRange, timeZone).raw : DEFAULT_RANGE;
|
const initialRange = urlRange ? getTimeRangeFromUrlMemoized(urlRange, timeZone).raw : DEFAULT_RANGE;
|
||||||
|
|
||||||
let newMode: ExploreMode;
|
let newMode: ExploreMode | undefined;
|
||||||
|
|
||||||
if (supportedModes.length) {
|
if (supportedModes.length) {
|
||||||
const urlModeIsValid = supportedModes.includes(urlMode);
|
const urlModeIsValid = supportedModes.includes(urlMode);
|
||||||
@ -391,7 +392,7 @@ function mapStateToProps(state: StoreState, { exploreId }: ExploreProps): Partia
|
|||||||
newMode = supportedModes[0];
|
newMode = supportedModes[0];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newMode = [ExploreMode.Metrics, ExploreMode.Logs].includes(urlMode) ? urlMode : null;
|
newMode = [ExploreMode.Metrics, ExploreMode.Logs].includes(urlMode) ? urlMode : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialUI = ui || DEFAULT_UI_STATE;
|
const initialUI = ui || DEFAULT_UI_STATE;
|
||||||
|
@ -39,17 +39,17 @@ const getStyles = (theme: GrafanaTheme) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
interface Props extends Themeable {
|
interface Props extends Themeable {
|
||||||
series: GraphSeriesXY[];
|
series?: GraphSeriesXY[];
|
||||||
width: number;
|
width: number;
|
||||||
absoluteRange: AbsoluteTimeRange;
|
absoluteRange: AbsoluteTimeRange;
|
||||||
loading: boolean;
|
loading?: boolean;
|
||||||
showPanel: boolean;
|
showPanel: boolean;
|
||||||
showBars: boolean;
|
showBars: boolean;
|
||||||
showLines: boolean;
|
showLines: boolean;
|
||||||
isStacked: boolean;
|
isStacked: boolean;
|
||||||
showingGraph: boolean;
|
showingGraph?: boolean;
|
||||||
showingTable: boolean;
|
showingTable?: boolean;
|
||||||
timeZone: TimeZone;
|
timeZone?: TimeZone;
|
||||||
onUpdateTimeRange: (absoluteRange: AbsoluteTimeRange) => void;
|
onUpdateTimeRange: (absoluteRange: AbsoluteTimeRange) => void;
|
||||||
onToggleGraph?: (showingGraph: boolean) => void;
|
onToggleGraph?: (showingGraph: boolean) => void;
|
||||||
onHiddenSeriesChanged?: (hiddenSeries: string[]) => void;
|
onHiddenSeriesChanged?: (hiddenSeries: string[]) => void;
|
||||||
@ -75,7 +75,7 @@ class UnThemedExploreGraphPanel extends PureComponent<Props, State> {
|
|||||||
onClickGraphButton = () => {
|
onClickGraphButton = () => {
|
||||||
const { onToggleGraph, showingGraph } = this.props;
|
const { onToggleGraph, showingGraph } = this.props;
|
||||||
if (onToggleGraph) {
|
if (onToggleGraph) {
|
||||||
onToggleGraph(showingGraph);
|
onToggleGraph(showingGraph ?? false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ export class ExploreTimeControls extends Component<Props> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { range, timeZone, splitted, syncedTimes, onChangeTimeSync, hideText } = this.props;
|
const { range, timeZone, splitted, syncedTimes, onChangeTimeSync, hideText } = this.props;
|
||||||
const timeSyncButton = splitted ? <TimeSyncButton onClick={onChangeTimeSync} isSynced={syncedTimes} /> : null;
|
const timeSyncButton = splitted ? <TimeSyncButton onClick={onChangeTimeSync} isSynced={syncedTimes} /> : undefined;
|
||||||
const timePickerCommonProps = {
|
const timePickerCommonProps = {
|
||||||
value: range,
|
value: range,
|
||||||
onChange: this.onChangeTimePicker,
|
onChange: this.onChangeTimePicker,
|
||||||
|
@ -54,18 +54,18 @@ interface StateProps {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
range: TimeRange;
|
range: TimeRange;
|
||||||
timeZone: TimeZone;
|
timeZone: TimeZone;
|
||||||
selectedDatasource: DataSourceSelectItem;
|
selectedDatasource?: DataSourceSelectItem;
|
||||||
splitted: boolean;
|
splitted: boolean;
|
||||||
syncedTimes: boolean;
|
syncedTimes: boolean;
|
||||||
refreshInterval: string;
|
refreshInterval?: string;
|
||||||
supportedModes: ExploreMode[];
|
supportedModes: ExploreMode[];
|
||||||
selectedMode: ExploreMode;
|
selectedMode: ExploreMode;
|
||||||
hasLiveOption: boolean;
|
hasLiveOption: boolean;
|
||||||
isLive: boolean;
|
isLive: boolean;
|
||||||
isPaused: boolean;
|
isPaused: boolean;
|
||||||
originPanelId: number;
|
originPanelId?: number;
|
||||||
queries: DataQuery[];
|
queries: DataQuery[];
|
||||||
datasourceLoading: boolean | null;
|
datasourceLoading?: boolean;
|
||||||
containerWidth: number;
|
containerWidth: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const styles = getStyles();
|
const styles = getStyles();
|
||||||
const originDashboardIsEditable = Number.isInteger(originPanelId);
|
const originDashboardIsEditable = originPanelId && Number.isInteger(originPanelId);
|
||||||
const panelReturnClasses = classNames('btn', 'navbar-button', {
|
const panelReturnClasses = classNames('btn', 'navbar-button', {
|
||||||
'btn--radius-right-0': originDashboardIsEditable,
|
'btn--radius-right-0': originDashboardIsEditable,
|
||||||
'navbar-button navbar-button--border-right-0': originDashboardIsEditable,
|
'navbar-button navbar-button--border-right-0': originDashboardIsEditable,
|
||||||
@ -234,7 +234,7 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{Number.isInteger(originPanelId) && !splitted && (
|
{originPanelId && Number.isInteger(originPanelId) && !splitted && (
|
||||||
<div className="explore-toolbar-content-item">
|
<div className="explore-toolbar-content-item">
|
||||||
<Tooltip content={'Return to panel'} placement="bottom">
|
<Tooltip content={'Return to panel'} placement="bottom">
|
||||||
<button className={panelReturnClasses} onClick={() => this.returnToPanel()}>
|
<button className={panelReturnClasses} onClick={() => this.returnToPanel()}>
|
||||||
|
@ -63,7 +63,7 @@ interface State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class LiveLogs extends PureComponent<Props, State> {
|
class LiveLogs extends PureComponent<Props, State> {
|
||||||
private liveEndDiv: HTMLDivElement = null;
|
private liveEndDiv: HTMLDivElement | null = null;
|
||||||
private scrollContainerRef = React.createRef<HTMLDivElement>();
|
private scrollContainerRef = React.createRef<HTMLDivElement>();
|
||||||
private lastScrollPos: number | null = null;
|
private lastScrollPos: number | null = null;
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ class LiveLogs extends PureComponent<Props, State> {
|
|||||||
componentDidUpdate(prevProps: Props) {
|
componentDidUpdate(prevProps: Props) {
|
||||||
if (!prevProps.isPaused && this.props.isPaused) {
|
if (!prevProps.isPaused && this.props.isPaused) {
|
||||||
// So we paused the view and we changed the content size, but we want to keep the relative offset from the bottom.
|
// So we paused the view and we changed the content size, but we want to keep the relative offset from the bottom.
|
||||||
if (this.lastScrollPos) {
|
if (this.lastScrollPos && this.scrollContainerRef.current) {
|
||||||
// There is last scroll pos from when user scrolled up a bit so go to that position.
|
// There is last scroll pos from when user scrolled up a bit so go to that position.
|
||||||
const { clientHeight, scrollHeight } = this.scrollContainerRef.current;
|
const { clientHeight, scrollHeight } = this.scrollContainerRef.current;
|
||||||
const scrollTop = scrollHeight - (this.lastScrollPos + clientHeight);
|
const scrollTop = scrollHeight - (this.lastScrollPos + clientHeight);
|
||||||
@ -123,7 +123,7 @@ class LiveLogs extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
rowsToRender = () => {
|
rowsToRender = () => {
|
||||||
const { isPaused } = this.props;
|
const { isPaused } = this.props;
|
||||||
let rowsToRender: LogRowModel[] = this.state.logRowsToRender;
|
let { logRowsToRender: rowsToRender = [] } = this.state;
|
||||||
if (!isPaused) {
|
if (!isPaused) {
|
||||||
// A perf optimisation here. Show just 100 rows when streaming and full length when the streaming is paused.
|
// A perf optimisation here. Show just 100 rows when streaming and full length when the streaming is paused.
|
||||||
rowsToRender = rowsToRender.slice(-100);
|
rowsToRender = rowsToRender.slice(-100);
|
||||||
|
@ -37,7 +37,7 @@ interface Props {
|
|||||||
dedupedRows?: LogRowModel[];
|
dedupedRows?: LogRowModel[];
|
||||||
|
|
||||||
width: number;
|
width: number;
|
||||||
highlighterExpressions: string[];
|
highlighterExpressions?: string[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
absoluteRange: AbsoluteTimeRange;
|
absoluteRange: AbsoluteTimeRange;
|
||||||
timeZone: TimeZone;
|
timeZone: TimeZone;
|
||||||
|
@ -30,7 +30,7 @@ import { LiveTailControls } from './useLiveTailControls';
|
|||||||
import { getLinksFromLogsField } from '../panel/panellinks/linkSuppliers';
|
import { getLinksFromLogsField } from '../panel/panellinks/linkSuppliers';
|
||||||
|
|
||||||
interface LogsContainerProps {
|
interface LogsContainerProps {
|
||||||
datasourceInstance: DataSourceApi | null;
|
datasourceInstance?: DataSourceApi;
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
|
|||||||
getLogRowContext = async (row: LogRowModel, options?: any): Promise<any> => {
|
getLogRowContext = async (row: LogRowModel, options?: any): Promise<any> => {
|
||||||
const { datasourceInstance } = this.props;
|
const { datasourceInstance } = this.props;
|
||||||
|
|
||||||
if (datasourceInstance) {
|
if (datasourceInstance?.getLogRowContext) {
|
||||||
return datasourceInstance.getLogRowContext(row, options);
|
return datasourceInstance.getLogRowContext(row, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,13 +45,13 @@ export default class QueryEditor extends PureComponent<QueryEditorProps, any> {
|
|||||||
target,
|
target,
|
||||||
refresh: () => {
|
refresh: () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.props.onQueryChange(target);
|
this.props.onQueryChange?.(target);
|
||||||
this.props.onExecuteQuery();
|
this.props.onExecuteQuery?.();
|
||||||
}, 1);
|
}, 1);
|
||||||
},
|
},
|
||||||
onQueryChange: () => {
|
onQueryChange: () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.props.onQueryChange(target);
|
this.props.onQueryChange?.(target);
|
||||||
}, 1);
|
}, 1);
|
||||||
},
|
},
|
||||||
events: exploreEvents,
|
events: exploreEvents,
|
||||||
@ -64,8 +64,8 @@ export default class QueryEditor extends PureComponent<QueryEditorProps, any> {
|
|||||||
this.angularScope = scopeProps.ctrl;
|
this.angularScope = scopeProps.ctrl;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.props.onQueryChange(target);
|
this.props.onQueryChange?.(target);
|
||||||
this.props.onExecuteQuery();
|
this.props.onExecuteQuery?.();
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,12 +134,12 @@ export class QueryRow extends PureComponent<QueryRowProps, QueryRowState> {
|
|||||||
const queryErrors = queryResponse.error && queryResponse.error.refId === query.refId ? [queryResponse.error] : [];
|
const queryErrors = queryResponse.error && queryResponse.error.refId === query.refId ? [queryResponse.error] : [];
|
||||||
let QueryField;
|
let QueryField;
|
||||||
|
|
||||||
if (mode === ExploreMode.Metrics && datasourceInstance.components.ExploreMetricsQueryField) {
|
if (mode === ExploreMode.Metrics && datasourceInstance.components?.ExploreMetricsQueryField) {
|
||||||
QueryField = datasourceInstance.components.ExploreMetricsQueryField;
|
QueryField = datasourceInstance.components.ExploreMetricsQueryField;
|
||||||
} else if (mode === ExploreMode.Logs && datasourceInstance.components.ExploreLogsQueryField) {
|
} else if (mode === ExploreMode.Logs && datasourceInstance.components?.ExploreLogsQueryField) {
|
||||||
QueryField = datasourceInstance.components.ExploreLogsQueryField;
|
QueryField = datasourceInstance.components.ExploreLogsQueryField;
|
||||||
} else {
|
} else {
|
||||||
QueryField = datasourceInstance.components.ExploreQueryField;
|
QueryField = datasourceInstance.components?.ExploreQueryField;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
canToggleEditorModes: boolean;
|
canToggleEditorModes: boolean;
|
||||||
isDisabled: boolean;
|
isDisabled?: boolean;
|
||||||
isNotStarted: boolean;
|
isNotStarted: boolean;
|
||||||
onClickToggleEditorMode: () => void;
|
onClickToggleEditorMode: () => void;
|
||||||
onClickToggleDisabled: () => void;
|
onClickToggleDisabled: () => void;
|
||||||
|
@ -21,7 +21,7 @@ type Props = {
|
|||||||
splitted: boolean;
|
splitted: boolean;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
onRun: () => void;
|
onRun: () => void;
|
||||||
refreshInterval: string;
|
refreshInterval?: string;
|
||||||
onChangeRefreshInterval: (interval: string) => void;
|
onChangeRefreshInterval: (interval: string) => void;
|
||||||
showDropdown: boolean;
|
showDropdown: boolean;
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ export default class Table extends PureComponent<TableProps> {
|
|||||||
if (link.className === 'link') {
|
if (link.className === 'link') {
|
||||||
const columnKey = column.Header().props.title;
|
const columnKey = column.Header().props.title;
|
||||||
const rowValue = rowInfo.row[columnKey];
|
const rowValue = rowInfo.row[columnKey];
|
||||||
this.props.onClickCell(columnKey, rowValue);
|
this.props.onClickCell?.(columnKey, rowValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -118,7 +118,7 @@ export interface LoadDatasourceReadyPayload {
|
|||||||
export interface ModifyQueriesPayload {
|
export interface ModifyQueriesPayload {
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
modification: QueryFixAction;
|
modification: QueryFixAction;
|
||||||
index: number;
|
index?: number;
|
||||||
modifier: (query: DataQuery, modification: QueryFixAction) => DataQuery;
|
modifier: (query: DataQuery, modification: QueryFixAction) => DataQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ export function changeQuery(
|
|||||||
exploreId: ExploreId,
|
exploreId: ExploreId,
|
||||||
query: DataQuery,
|
query: DataQuery,
|
||||||
index: number,
|
index: number,
|
||||||
override: boolean
|
override = false
|
||||||
): ThunkResult<void> {
|
): ThunkResult<void> {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
// Null query means reset
|
// Null query means reset
|
||||||
@ -389,8 +389,8 @@ export function loadDatasource(exploreId: ExploreId, instance: DataSourceApi, or
|
|||||||
export function modifyQueries(
|
export function modifyQueries(
|
||||||
exploreId: ExploreId,
|
exploreId: ExploreId,
|
||||||
modification: QueryFixAction,
|
modification: QueryFixAction,
|
||||||
index: number,
|
modifier: any,
|
||||||
modifier: any
|
index?: number
|
||||||
): ThunkResult<void> {
|
): ThunkResult<void> {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch(modifyQueriesAction({ exploreId, modification, index, modifier }));
|
dispatch(modifyQueriesAction({ exploreId, modification, index, modifier }));
|
||||||
|
@ -59,7 +59,7 @@ const state: any = {
|
|||||||
describe('Deduplication selector', () => {
|
describe('Deduplication selector', () => {
|
||||||
it('returns the same rows if no deduplication', () => {
|
it('returns the same rows if no deduplication', () => {
|
||||||
const dedups = deduplicatedRowsSelector(state as ExploreItemState);
|
const dedups = deduplicatedRowsSelector(state as ExploreItemState);
|
||||||
expect(dedups.length).toBe(11);
|
expect(dedups?.length).toBe(11);
|
||||||
expect(dedups).toBe(state.logsResult.rows);
|
expect(dedups).toBe(state.logsResult.rows);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ describe('Deduplication selector', () => {
|
|||||||
...state,
|
...state,
|
||||||
dedupStrategy: LogsDedupStrategy.numbers,
|
dedupStrategy: LogsDedupStrategy.numbers,
|
||||||
} as ExploreItemState);
|
} as ExploreItemState);
|
||||||
expect(dedups.length).toBe(2);
|
expect(dedups?.length).toBe(2);
|
||||||
expect(dedups).not.toBe(state.logsResult.rows);
|
expect(dedups).not.toBe(state.logsResult.rows);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ describe('Deduplication selector', () => {
|
|||||||
...state,
|
...state,
|
||||||
hiddenLogLevels: [LogLevel.debug],
|
hiddenLogLevels: [LogLevel.debug],
|
||||||
} as ExploreItemState);
|
} as ExploreItemState);
|
||||||
expect(dedups.length).toBe(2);
|
expect(dedups?.length).toBe(2);
|
||||||
expect(dedups).not.toBe(state.logsResult.rows);
|
expect(dedups).not.toBe(state.logsResult.rows);
|
||||||
|
|
||||||
dedups = deduplicatedRowsSelector({
|
dedups = deduplicatedRowsSelector({
|
||||||
@ -86,7 +86,7 @@ describe('Deduplication selector', () => {
|
|||||||
hiddenLogLevels: [LogLevel.debug],
|
hiddenLogLevels: [LogLevel.debug],
|
||||||
} as ExploreItemState);
|
} as ExploreItemState);
|
||||||
|
|
||||||
expect(dedups.length).toBe(2);
|
expect(dedups?.length).toBe(2);
|
||||||
expect(dedups).not.toBe(state.logsResult.rows);
|
expect(dedups).not.toBe(state.logsResult.rows);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ export class ResultProcessor {
|
|||||||
private timeZone: TimeZone
|
private timeZone: TimeZone
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
getGraphResult(): GraphSeriesXY[] {
|
getGraphResult(): GraphSeriesXY[] | null {
|
||||||
if (this.state.mode !== ExploreMode.Metrics) {
|
if (this.state.mode !== ExploreMode.Metrics) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ export class ResultProcessor {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTableResult(): TableModel {
|
getTableResult(): TableModel | null {
|
||||||
if (this.state.mode !== ExploreMode.Metrics) {
|
if (this.state.mode !== ExploreMode.Metrics) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ export class ResultProcessor {
|
|||||||
return mergeTablesIntoModel(new TableModel(), ...tables);
|
return mergeTablesIntoModel(new TableModel(), ...tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLogsResult(): LogsModel {
|
getLogsResult(): LogsModel | null {
|
||||||
if (this.state.mode !== ExploreMode.Logs) {
|
if (this.state.mode !== ExploreMode.Logs) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ export interface ExploreItemState {
|
|||||||
/**
|
/**
|
||||||
* Datasource instance that has been selected. Datasource-specific logic can be run on this object.
|
* Datasource instance that has been selected. Datasource-specific logic can be run on this object.
|
||||||
*/
|
*/
|
||||||
datasourceInstance: DataSourceApi | null;
|
datasourceInstance?: DataSourceApi;
|
||||||
/**
|
/**
|
||||||
* Current data source name or null if default
|
* Current data source name or null if default
|
||||||
*/
|
*/
|
||||||
@ -73,7 +73,7 @@ export interface ExploreItemState {
|
|||||||
/**
|
/**
|
||||||
* True if the datasource is loading. `null` if the loading has not started yet.
|
* True if the datasource is loading. `null` if the loading has not started yet.
|
||||||
*/
|
*/
|
||||||
datasourceLoading: boolean | null;
|
datasourceLoading?: boolean;
|
||||||
/**
|
/**
|
||||||
* True if there is no datasource to be selected.
|
* True if there is no datasource to be selected.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user