Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
CAWilson94 authored Nov 8, 2024
2 parents 7066db5 + cbebdae commit 81f9cdf
Show file tree
Hide file tree
Showing 21 changed files with 197 additions and 56 deletions.
84 changes: 84 additions & 0 deletions packages/kbn-esql-ast/src/parser/__tests__/function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

import { parse } from '..';
import { EsqlQuery } from '../../query';
import { Walker } from '../../walker';

describe('function AST nodes', () => {
Expand Down Expand Up @@ -323,3 +324,86 @@ describe('function AST nodes', () => {
});
});
});

describe('location', () => {
const getFunctionTexts = (src: string) => {
const query = EsqlQuery.fromSrc(src);
const functions = Walker.matchAll(query.ast, { type: 'function' });
const texts: string[] = functions.map((fn) => {
return [...src].slice(fn.location.min, fn.location.max + 1).join('');
});

return texts;
};

it('correctly cuts out function source texts', () => {
const texts = getFunctionTexts(
'FROM index | LIMIT 1 | STATS agg() | LIMIT 2 | STATS max(a, b, c), max2(d.e)'
);

expect(texts).toEqual(['agg()', 'max(a, b, c)', 'max2(d.e)']);
});

it('functions in binary expressions', () => {
const texts = getFunctionTexts('FROM index | STATS foo = agg(f1) + agg(f2), a.b = agg(f3)');

expect(texts).toEqual([
'foo = agg(f1) + agg(f2)',
'agg(f1) + agg(f2)',
'agg(f1)',
'agg(f2)',
'a.b = agg(f3)',
'agg(f3)',
]);
});

it('with the simplest comment after function name identifier', () => {
const texts1 = getFunctionTexts('FROM index | STATS agg/* */(1)');
expect(texts1).toEqual(['agg/* */(1)']);

const texts2 = getFunctionTexts('FROM index | STATS agg/* A */(a)');
expect(texts2).toEqual(['agg/* A */(a)']);

const texts3 = getFunctionTexts('FROM index | STATS agg /* A */ (*)');
expect(texts3).toEqual(['agg /* A */ (*)']);
});

it('with the simplest emoji comment after function name identifier', () => {
const texts = getFunctionTexts('FROM index | STATS agg/* 😎 */(*)');
expect(texts).toEqual(['agg/* 😎 */(*)']);
});

it('with the simplest emoji comment after function name identifier, followed by another arg', () => {
const texts = getFunctionTexts('FROM index | STATS agg/* 😎 */(*), abc');
expect(texts).toEqual(['agg/* 😎 */(*)']);
});

it('simple emoji comment twice', () => {
const texts = getFunctionTexts('FROM index | STATS agg/* 😎 */(*), max/* 😎 */(*)');
expect(texts).toEqual(['agg/* 😎 */(*)', 'max/* 😎 */(*)']);
});

it('with comment and emoji after function name identifier', () => {
const texts = getFunctionTexts('FROM index | STATS agg /* haha 😅 */ (*)');

expect(texts).toEqual(['agg /* haha 😅 */ (*)']);
});

it('with comment inside argument list', () => {
const texts = getFunctionTexts('FROM index | STATS agg ( /* haha 😅 */ )');

expect(texts).toEqual(['agg ( /* haha 😅 */ )']);
});

it('with emoji and comment in argument lists', () => {
const texts = getFunctionTexts(
'FROM index | STATS agg( /* haha 😅 */ max(foo), bar, baz), test( /* asdf */ * /* asdf */)'
);

expect(texts).toEqual([
'agg( /* haha 😅 */ max(foo), bar, baz)',
'max(foo)',
'test( /* asdf */ * /* asdf */)',
]);
});
});
13 changes: 6 additions & 7 deletions packages/kbn-esql-ast/src/parser/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,16 @@ export const formatIdentifierParts = (parts: string[]): string =>
parts.map(formatIdentifier).join('.');

export const getPosition = (
token: Pick<Token, 'start' | 'stop'> | null,
lastToken?: Pick<Token, 'stop'> | undefined
start: Pick<Token, 'start' | 'stop'> | null,
stop?: Pick<Token, 'stop'> | undefined
) => {
if (!token || token.start < 0) {
if (!start || start.start < 0) {
return { min: 0, max: 0 };
}
const endFirstToken = token.stop > -1 ? Math.max(token.stop + 1, token.start) : undefined;
const endLastToken = lastToken?.stop;
const endFirstToken = start.stop > -1 ? Math.max(start.stop + 1, start.start) : undefined;
return {
min: token.start,
max: endLastToken ?? endFirstToken ?? Infinity,
min: start.start,
max: stop?.stop ?? endFirstToken ?? Infinity,
};
};

Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pageLoadAssetSize:
actions: 20000
advancedSettings: 27596
aiAssistantManagementSelection: 19146
aiops: 10000
aiops: 16000
alerting: 106936
apm: 64385
banners: 17946
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { createAction } from '@kbn/ui-actions-plugin/public';
import type { CoreStart } from '@kbn/core/public';
import { ACTION_CATEGORIZE_FIELD, type CategorizeFieldContext } from '@kbn/ml-ui-actions';
import type { AiopsPluginStartDeps } from '../../types';
import { showCategorizeFlyout } from './show_flyout';

export const createCategorizeFieldAction = (coreStart: CoreStart, plugins: AiopsPluginStartDeps) =>
createAction<CategorizeFieldContext>({
Expand All @@ -25,6 +24,7 @@ export const createCategorizeFieldAction = (coreStart: CoreStart, plugins: Aiops
},
execute: async (context: CategorizeFieldContext) => {
const { field, dataView, originatingApp, additionalFilter } = context;
const { showCategorizeFlyout } = await import('./show_flyout');
showCategorizeFlyout(field, dataView, coreStart, plugins, originatingApp, additionalFilter);
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

export type { LogCategorizationAppStateProps } from './log_categorization_app_state';
import { LogCategorizationAppState } from './log_categorization_app_state';
export { createCategorizeFieldAction } from './categorize_field_actions';

// required for dynamic import using React.lazy()
// eslint-disable-next-line import/no-default-export
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export async function showCategorizeFlyout(
): Promise<void> {
const { overlays, application, i18n } = coreStart;

return new Promise(async (resolve, reject) => {
return new Promise((resolve, reject) => {
try {
const onFlyoutClose = () => {
flyoutSession.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ import type { DataView } from '@kbn/data-views-plugin/common';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common';
import type { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public';
import { i18n } from '@kbn/i18n';
import {
apiHasExecutionContext,
fetch$,
initializeTimeRange,
initializeTitles,
useBatchedPublishingSubjects,
} from '@kbn/presentation-publishing';

import fastIsEqual from 'fast-deep-equal';
import { cloneDeep } from 'lodash';
Expand Down Expand Up @@ -61,6 +54,14 @@ export const getChangePointChartEmbeddableFactory = (
return serializedState;
},
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {
const {
apiHasExecutionContext,
fetch$,
initializeTimeRange,
initializeTitles,
useBatchedPublishingSubjects,
} = await import('@kbn/presentation-publishing');

const [coreStart, pluginStart] = await getStartServices();

const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ import type { DataView } from '@kbn/data-views-plugin/common';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common';
import type { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public';
import { i18n } from '@kbn/i18n';
import {
apiHasExecutionContext,
fetch$,
initializeTimeRange,
initializeTitles,
useBatchedPublishingSubjects,
} from '@kbn/presentation-publishing';
import fastIsEqual from 'fast-deep-equal';
import { cloneDeep } from 'lodash';
import React, { useMemo } from 'react';
Expand Down Expand Up @@ -58,6 +51,14 @@ export const getPatternAnalysisEmbeddableFactory = (
return serializedState;
},
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {
const {
apiHasExecutionContext,
fetch$,
initializeTimeRange,
initializeTitles,
useBatchedPublishingSubjects,
} = await import('@kbn/presentation-publishing');

const [coreStart, pluginStart] = await getStartServices();

const {
Expand Down
28 changes: 7 additions & 21 deletions x-pack/plugins/aiops/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@
import type { CoreStart, Plugin } from '@kbn/core/public';
import { type CoreSetup } from '@kbn/core/public';
import { firstValueFrom } from 'rxjs';
import { dynamic } from '@kbn/shared-ux-utility';

import { getChangePointDetectionComponent } from './shared_components';
import { LogCategorizationForDiscover as PatternAnalysisComponent } from './shared_lazy_components';
import type {
AiopsPluginSetup,
AiopsPluginSetupDeps,
AiopsPluginStart,
AiopsPluginStartDeps,
} from './types';
import { registerEmbeddables } from './embeddables';
import { registerAiopsUiActions } from './ui_actions';
import { registerChangePointChartsAttachment } from './cases/register_change_point_charts_attachment';

export type AiopsCoreSetup = CoreSetup<AiopsPluginStartDeps, AiopsPluginStart>;

Expand All @@ -27,20 +30,8 @@ export class AiopsPlugin
core: AiopsCoreSetup,
{ embeddable, cases, licensing, uiActions }: AiopsPluginSetupDeps
) {
Promise.all([
firstValueFrom(licensing.license$),
import('./embeddables'),
import('./ui_actions'),
import('./cases/register_change_point_charts_attachment'),
core.getStartServices(),
]).then(
([
license,
{ registerEmbeddables },
{ registerAiopsUiActions },
{ registerChangePointChartsAttachment },
[coreStart, pluginStart],
]) => {
Promise.all([firstValueFrom(licensing.license$), core.getStartServices()]).then(
([license, [coreStart, pluginStart]]) => {
const { canUseAiops } = coreStart.application.capabilities.ml;

if (license.hasAtLeast('platinum') && canUseAiops) {
Expand Down Expand Up @@ -69,12 +60,7 @@ export class AiopsPlugin
);
return getPatternAnalysisAvailable(plugins.licensing);
},
PatternAnalysisComponent: dynamic(
async () =>
import(
'./components/log_categorization/log_categorization_for_embeddable/log_categorization_for_discover_wrapper'
)
),
PatternAnalysisComponent,
};
}

Expand Down
20 changes: 20 additions & 0 deletions x-pack/plugins/aiops/public/shared_lazy_components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { EuiErrorBoundary, EuiSkeletonText } from '@elastic/eui';
import type { LogRateAnalysisAppStateProps } from './components/log_rate_analysis';
import type { LogRateAnalysisContentWrapperProps } from './components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper';
import type { LogCategorizationAppStateProps } from './components/log_categorization';
import type { LogCategorizationEmbeddableWrapperProps } from './components/log_categorization/log_categorization_for_embeddable/log_categorization_for_discover_wrapper';
import type { ChangePointDetectionAppStateProps } from './components/change_point_detection';

const LogRateAnalysisAppStateLazy = React.lazy(() => import('./components/log_rate_analysis'));
Expand Down Expand Up @@ -58,6 +59,25 @@ export const LogCategorization: FC<LogCategorizationAppStateProps> = (props) =>
</LazyWrapper>
);

const LogCategorizationForDiscoverLazy = React.lazy(
() =>
import(
'./components/log_categorization/log_categorization_for_embeddable/log_categorization_for_discover_wrapper'
)
);

/**
* Lazy-wrapped LogCategorizationForDiscover React component
* @param {LogCategorizationEmbeddableWrapperProps} props - properties specifying the data on which to run the analysis.
*/
export const LogCategorizationForDiscover: FC<LogCategorizationEmbeddableWrapperProps> = (
props
) => (
<LazyWrapper>
<LogCategorizationForDiscoverLazy {...props} />
</LazyWrapper>
);

const ChangePointDetectionLazy = React.lazy(() => import('./components/change_point_detection'));
/**
* Lazy-wrapped ChangePointDetectionAppStateProps React component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
*/

import { isPopulatedObject } from '@kbn/ml-is-populated-object';
import { apiIsOfType, type EmbeddableApiContext } from '@kbn/presentation-publishing';
import type { EmbeddableApiContext } from '@kbn/presentation-publishing';
import { apiIsOfType } from '@kbn/presentation-publishing/interfaces/has_type';
import { EMBEDDABLE_CHANGE_POINT_CHART_TYPE } from '@kbn/aiops-change-point-detection/constants';
import type { ChangePointEmbeddableApi } from '../embeddables/change_point_chart/types';

Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/aiops/public/ui_actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { CoreStart } from '@kbn/core/public';
import { createAddChangePointChartAction } from './create_change_point_chart';
import { createOpenChangePointInMlAppAction } from './open_change_point_ml';
import type { AiopsPluginStartDeps } from '../types';
import { createCategorizeFieldAction } from '../components/log_categorization';
import { createCategorizeFieldAction } from '../components/log_categorization/categorize_field_actions';
import { createAddPatternAnalysisEmbeddableAction } from './create_pattern_analysis_action';
import { createAddLogRateAnalysisEmbeddableAction } from './create_log_rate_analysis_actions';

Expand Down
13 changes: 8 additions & 5 deletions x-pack/plugins/aiops/public/ui_actions/open_change_point_ml.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { i18n } from '@kbn/i18n';
import type { CoreStart } from '@kbn/core/public';
import type { TimeRange } from '@kbn/es-query';
import { apiHasParentApi, apiPublishesTimeRange } from '@kbn/presentation-publishing';
import type { ChangePointEmbeddableApi } from '../embeddables/change_point_chart/types';
import type { AiopsPluginStartDeps } from '../types';
import type { ChangePointChartActionContext } from './change_point_action_context';
import { isChangePointChartEmbeddableContext } from './change_point_action_context';

export const OPEN_CHANGE_POINT_IN_ML_APP_ACTION = 'openChangePointInMlAppAction';

export const getEmbeddableTimeRange = (
const getEmbeddableTimeRange = async (
embeddable: ChangePointEmbeddableApi
): TimeRange | undefined => {
): Promise<TimeRange | undefined> => {
const { apiHasParentApi, apiPublishesTimeRange } = await import('@kbn/presentation-publishing');

let timeRange = embeddable.timeRange$?.getValue();

if (!timeRange && apiHasParentApi(embeddable) && apiPublishesTimeRange(embeddable.parentApi)) {
Expand All @@ -45,6 +45,7 @@ export function createOpenChangePointInMlAppAction(
defaultMessage: 'Open in AIOps Labs',
}),
async getHref(context): Promise<string | undefined> {
const { isChangePointChartEmbeddableContext } = await import('./change_point_action_context');
if (!isChangePointChartEmbeddableContext(context)) {
throw new IncompatibleActionError();
}
Expand All @@ -57,7 +58,7 @@ export function createOpenChangePointInMlAppAction(
page: 'aiops/change_point_detection',
pageState: {
index: dataViewId.getValue(),
timeRange: getEmbeddableTimeRange(context.embeddable),
timeRange: await getEmbeddableTimeRange(context.embeddable),
fieldConfigs: [
{
fn: fn.getValue(),
Expand All @@ -69,6 +70,7 @@ export function createOpenChangePointInMlAppAction(
});
},
async execute(context) {
const { isChangePointChartEmbeddableContext } = await import('./change_point_action_context');
if (!isChangePointChartEmbeddableContext(context)) {
throw new IncompatibleActionError();
}
Expand All @@ -78,6 +80,7 @@ export function createOpenChangePointInMlAppAction(
}
},
async isCompatible(context) {
const { isChangePointChartEmbeddableContext } = await import('./change_point_action_context');
return isChangePointChartEmbeddableContext(context);
},
};
Expand Down
Loading

0 comments on commit 81f9cdf

Please sign in to comment.