Skip to content

Commit

Permalink
Merge branch 'main' into 167887-esql-saved-search-v3
Browse files Browse the repository at this point in the history
  • Loading branch information
jughosta authored Apr 5, 2024
2 parents 280323d + bacad3a commit d49f1e3
Show file tree
Hide file tree
Showing 23 changed files with 588 additions and 198 deletions.
2 changes: 2 additions & 0 deletions packages/kbn-esql-validation-autocomplete/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,5 @@ export {
getPolicyHelper,
getSourcesHelper,
} from './src/shared/resources_helpers';

export { wrapAsEditorMessage } from './src/code_actions/utils';
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import { getActions } from './actions';
import { validateQuery } from '../validation/validation';
import { getAllFunctions } from '../shared/helpers';
import { wrapAsEditorMessage } from './testing_utils';
import { getAstAndSyntaxErrors } from '@kbn/esql-ast';

function getCallbackMocks() {
Expand Down Expand Up @@ -82,8 +81,7 @@ function testQuickFixesFn(
callbackMocks
);

const monacoErrors = wrapAsEditorMessage('error', errors);
const actions = await getActions(statement, monacoErrors, getAstAndSyntaxErrors, callbackMocks);
const actions = await getActions(statement, errors, getAstAndSyntaxErrors, callbackMocks);
const edits = actions.map(({ edits: actionEdits }) => actionEdits[0].text);
expect(edits).toEqual(
!options || !options.equalityCheck || options.equalityCheck === 'equal'
Expand Down Expand Up @@ -269,9 +267,8 @@ describe('quick fixes logic', () => {
undefined,
callbackMocks
);
const monacoErrors = wrapAsEditorMessage('error', errors);
try {
await getActions(statement, monacoErrors, getAstAndSyntaxErrors, {
await getActions(statement, errors, getAstAndSyntaxErrors, {
getFieldsFor: undefined,
getSources: undefined,
getPolicies: undefined,
Expand All @@ -291,9 +288,8 @@ describe('quick fixes logic', () => {
undefined,
callbackMocks
);
const monacoErrors = wrapAsEditorMessage('error', errors);
try {
await getActions(statement, monacoErrors, getAstAndSyntaxErrors, undefined);
await getActions(statement, errors, getAstAndSyntaxErrors, undefined);
} catch {
fail('Should not throw');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { i18n } from '@kbn/i18n';
import levenshtein from 'js-levenshtein';
import type { AstProviderFn, ESQLAst, ESQLCommand, EditorError } from '@kbn/esql-ast';
import type { AstProviderFn, ESQLAst, ESQLCommand, EditorError, ESQLMessage } from '@kbn/esql-ast';
import {
getFieldsByTypeHelper,
getPolicyHelper,
Expand All @@ -23,6 +23,7 @@ import { ESQLCallbacks } from '../shared/types';
import { buildQueryForFieldsFromSource } from '../validation/helpers';
import { DOUBLE_BACKTICK, SINGLE_TICK_REGEX } from '../shared/constants';
import type { CodeAction, Callbacks } from './types';
import { wrapAsEditorMessage } from './utils';

function getFieldsByTypeRetriever(queryString: string, resourceRetriever?: ESQLCallbacks) {
const helpers = getFieldsByTypeHelper(queryString, resourceRetriever);
Expand Down Expand Up @@ -308,14 +309,15 @@ function inferCodeFromError(error: EditorError & { owner?: string }, rawText: st

export async function getActions(
innerText: string,
markers: EditorError[],
markers: Array<ESQLMessage | EditorError>,
astProvider: AstProviderFn,
resourceRetriever?: ESQLCallbacks
): Promise<CodeAction[]> {
const actions: CodeAction[] = [];
if (markers.length === 0) {
return actions;
}
const editorMarkers = wrapAsEditorMessage('error', markers);
const { ast } = await astProvider(innerText);

const queryForFields = buildQueryForFieldsFromSource(innerText, ast);
Expand All @@ -335,7 +337,7 @@ export async function getActions(
// Markers are sent only on hover and are limited to the hovered area
// so unless there are multiple error/markers for the same area, there's just one
// in some cases, like syntax + semantic errors (i.e. unquoted fields eval field-1 ), there might be more than one
for (const error of markers) {
for (const error of editorMarkers) {
const code = error.code ?? inferCodeFromError(error, innerText);
switch (code) {
case 'unknownColumn':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,40 @@ describe('getAddPanelActionMenuItems', () => {
isCompatible: () => Promise.resolve(true),
execute: jest.fn(),
},
{
id: 'TEST_ACTION_01',
type: 'TEST_ACTION_01',
getDisplayName: () => 'Action name 01',
getIconType: () => 'pencil',
getDisplayNameTooltip: () => 'Action tooltip',
isCompatible: () => Promise.resolve(true),
execute: jest.fn(),
grouping: [
{
id: 'groupedAddPanelAction',
getDisplayName: () => 'Custom group',
getIconType: () => 'logoElasticsearch',
},
],
},
{
id: 'TEST_ACTION_02',
type: 'TEST_ACTION_02',
getDisplayName: () => 'Action name',
getIconType: () => 'pencil',
getDisplayNameTooltip: () => 'Action tooltip',
isCompatible: () => Promise.resolve(true),
execute: jest.fn(),
grouping: [
{
id: 'groupedAddPanelAction',
getDisplayName: () => 'Custom group',
getIconType: () => 'logoElasticsearch',
},
],
},
];
const items = getAddPanelActionMenuItems(
const [items, grouped] = getAddPanelActionMenuItems(
getMockPresentationContainer(),
registeredActions,
jest.fn()
Expand All @@ -36,10 +68,38 @@ describe('getAddPanelActionMenuItems', () => {
toolTipContent: 'Action tooltip',
},
]);
expect(grouped).toStrictEqual({
groupedAddPanelAction: {
id: 'groupedAddPanelAction',
title: 'Custom group',
icon: 'logoElasticsearch',
items: [
{
'data-test-subj': 'create-action-Action name 01',
icon: 'pencil',
name: 'Action name 01',
onClick: expect.any(Function),
toolTipContent: 'Action tooltip',
},
{
'data-test-subj': 'create-action-Action name',
icon: 'pencil',
name: 'Action name',
onClick: expect.any(Function),
toolTipContent: 'Action tooltip',
},
],
},
});
});

it('returns empty array if no actions have been registered', async () => {
const items = getAddPanelActionMenuItems(getMockPresentationContainer(), [], jest.fn());
const [items, grouped] = getAddPanelActionMenuItems(
getMockPresentationContainer(),
[],
jest.fn()
);
expect(items).toStrictEqual([]);
expect(grouped).toStrictEqual({});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
*/
import type { ActionExecutionContext, Action } from '@kbn/ui-actions-plugin/public';
import { PresentationContainer } from '@kbn/presentation-containers';
import type {
EuiContextMenuPanelDescriptor,
EuiContextMenuPanelItemDescriptor,
} from '@elastic/eui';
import { addPanelMenuTrigger } from '../../triggers';

const onAddPanelActionClick =
Expand All @@ -26,25 +30,53 @@ const onAddPanelActionClick =
} else action.execute(context);
};

export type GroupedAddPanelActions = EuiContextMenuPanelDescriptor & {
icon?: string;
};

export const getAddPanelActionMenuItems = (
api: PresentationContainer,
actions: Array<Action<object>> | undefined,
closePopover: () => void
) => {
return (
actions?.map((item) => {
const context = {
embeddable: api,
trigger: addPanelMenuTrigger,
};
const actionName = item.getDisplayName(context);
return {
name: actionName,
icon: item.getIconType(context),
onClick: onAddPanelActionClick(item, context, closePopover),
'data-test-subj': `create-action-${actionName}`,
toolTipContent: item?.getDisplayNameTooltip?.(context),
};
}) ?? []
);
): [EuiContextMenuPanelItemDescriptor[], Record<string, GroupedAddPanelActions>] => {
const ungrouped: EuiContextMenuPanelItemDescriptor[] = [];
const grouped: Record<string, GroupedAddPanelActions> = {};

const context = {
embeddable: api,
trigger: addPanelMenuTrigger,
};

const getMenuItem = (item: Action<object>) => {
const actionName = item.getDisplayName(context);

return {
name: actionName,
icon: item.getIconType(context),
onClick: onAddPanelActionClick(item, context, closePopover),
'data-test-subj': `create-action-${actionName}`,
toolTipContent: item?.getDisplayNameTooltip?.(context),
};
};

actions?.forEach((item) => {
if (Array.isArray(item.grouping)) {
item.grouping.forEach((group) => {
if (!grouped[group.id]) {
grouped[group.id] = {
id: group.id,
icon: group.getIconType ? group.getIconType(context) : undefined,
title: group.getDisplayName ? group.getDisplayName(context) : undefined,
items: [],
};
}

grouped[group.id]!.items!.push(getMenuItem(item));
});
} else {
ungrouped.push(getMenuItem(item));
}
});

return [ungrouped, grouped];
};
Loading

0 comments on commit d49f1e3

Please sign in to comment.