Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

esql autocomplete will only suggest creating an enrich policy if you … #201491

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/kbn-esql-editor/src/esql_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const ESQLEditor = memo(function ESQLEditor({
hideQueryHistory,
hasOutline,
displayDocumentationAsFlyout,
canCreateEnrichPolicy = false,
}: ESQLEditorProps) {
const popoverRef = useRef<HTMLDivElement>(null);
const datePickerOpenStatusRef = useRef<boolean>(false);
Expand Down Expand Up @@ -389,6 +390,7 @@ export const ESQLEditor = memo(function ESQLEditor({
},
// @ts-expect-error To prevent circular type import, type defined here is partial of full client
getFieldsMetadata: fieldsMetadata?.getClient(),
canCreateEnrichPolicy: () => canCreateEnrichPolicy,
};
return callbacks;
}, [
Expand All @@ -404,6 +406,7 @@ export const ESQLEditor = memo(function ESQLEditor({
indexManagementApiService,
histogramBarTarget,
fieldsMetadata,
canCreateEnrichPolicy,
]);

const queryRunButtonProperties = useMemo(() => {
Expand Down
2 changes: 2 additions & 0 deletions packages/kbn-esql-editor/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ export interface ESQLEditorProps {

/** adds a documentation icon in the footer which opens the inline docs as a flyout **/
displayDocumentationAsFlyout?: boolean;

canCreateEnrichPolicy?: boolean;
}

export interface ESQLEditorDeps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ export function createCustomCallbackMocks(
matchField: string;
enrichFields: string[];
}>
) {
): ESQLCallbacks {
const finalColumnsSinceLastCommand =
customColumnsSinceLastCommand ||
fields.filter(({ type }) => !NOT_SUGGESTED_TYPES.includes(type));
Expand All @@ -281,6 +281,7 @@ export function createCustomCallbackMocks(
getColumnsFor: jest.fn(async () => finalColumnsSinceLastCommand),
getSources: jest.fn(async () => finalSources),
getPolicies: jest.fn(async () => finalPolicies),
canCreateEnrichPolicy: jest.fn(() => true),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ export async function suggest(
getFieldsMap,
getPolicies,
getPolicyMetadata,
resourceRetriever?.canCreateEnrichPolicy
? resourceRetriever?.canCreateEnrichPolicy
: () => false,
resourceRetriever?.getPreferences,
fullAst
);
Expand Down Expand Up @@ -398,6 +401,7 @@ async function getSuggestionsWithinCommandExpression(
getFieldsMap: GetFieldsMapFn,
getPolicies: GetPoliciesFn,
getPolicyMetadata: GetPolicyMetadataFn,
canCreateEnrichPolicy: () => boolean,
getPreferences?: () => Promise<{ histogramBarTarget: number } | undefined>,
fullAst?: ESQLAst
) {
Expand Down Expand Up @@ -431,7 +435,8 @@ async function getSuggestionsWithinCommandExpression(
getColumnsByType,
getFieldsMap,
getPolicies,
getPolicyMetadata
getPolicyMetadata,
canCreateEnrichPolicy
);
}
}
Expand All @@ -456,7 +461,8 @@ async function getExpressionSuggestionsByType(
getFieldsByType: GetColumnsByTypeFn,
getFieldsMap: GetFieldsMapFn,
getPolicies: GetPoliciesFn,
getPolicyMetadata: GetPolicyMetadataFn
getPolicyMetadata: GetPolicyMetadataFn,
canCreateEnrichPolicy: () => boolean
) {
const commandDef = getCommandDefinition(command.name);
const { argIndex, prevIndex, lastArg, nodeArg } = extractArgMeta(command, node);
Expand Down Expand Up @@ -880,7 +886,12 @@ async function getExpressionSuggestionsByType(
});
});
}
suggestions.push(...(policies.length ? policies : [buildNoPoliciesAvailableDefinition()]));

suggestions.push(
...(policies.length
? policies
: [buildNoPoliciesAvailableDefinition(canCreateEnrichPolicy())])
);
} else {
const indexes = getSourcesFromCommands(commands, 'index');
const lastIndex = indexes[indexes.length - 1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,26 +412,36 @@ export const buildSettingDefinitions = (
}));
};

export const buildNoPoliciesAvailableDefinition = (): SuggestionRawDefinition => ({
label: i18n.translate('kbn-esql-validation-autocomplete.esql.autocomplete.noPoliciesLabel', {
defaultMessage: 'No available policy',
}),
text: '',
kind: 'Issue',
detail: i18n.translate(
'kbn-esql-validation-autocomplete.esql.autocomplete.noPoliciesLabelsFound',
{
defaultMessage: 'Click to create',
}
),
sortText: 'D',
command: {
id: 'esql.policies.create',
title: i18n.translate('kbn-esql-validation-autocomplete.esql.autocomplete.createNewPolicy', {
defaultMessage: 'Click to create',
export const buildNoPoliciesAvailableDefinition = (
canCreateEnrichPolicy: boolean
): SuggestionRawDefinition => {
const noPoliciesDef: SuggestionRawDefinition = {
label: i18n.translate('kbn-esql-validation-autocomplete.esql.autocomplete.noPoliciesLabel', {
defaultMessage: 'No available policy',
}),
},
});
text: '',
kind: 'Issue',
detail: '',
};

if (canCreateEnrichPolicy) {
noPoliciesDef.detail = i18n.translate(
'kbn-esql-validation-autocomplete.esql.autocomplete.noPoliciesLabelsFound',
{
defaultMessage: 'Click to create',
}
);
noPoliciesDef.sortText = 'D';
noPoliciesDef.command = {
id: 'esql.policies.create',
title: i18n.translate('kbn-esql-validation-autocomplete.esql.autocomplete.createNewPolicy', {
defaultMessage: 'Click to create',
}),
};
}

return noPoliciesDef;
};

export function getUnitDuration(unit: number = 1) {
const filteredTimeLiteral = timeUnitsToSuggest.filter(({ name }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface ESQLCallbacks {
>;
getPreferences?: () => Promise<{ histogramBarTarget: number }>;
getFieldsMetadata?: Promise<PartialFieldsMetadataClient>;
canCreateEnrichPolicy?: () => boolean;
}

export type ReasonTypes = 'missingCommand' | 'unsupportedFunction' | 'unknownFunction';
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,7 @@ describe('validation logic', () => {
getColumnsFor: /Unknown column|Argument of|it is unsupported or not indexed/,
getPreferences: /Unknown/,
getFieldsMetadata: /Unknown/,
canCreateEnrichPolicy: /Unknown/,
};
return excludedCallback.map((callback) => contentByCallback[callback]) || [];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,7 @@ export const ignoreErrorsMap: Record<keyof ESQLCallbacks, ErrorTypes[]> = {
getPolicies: ['unknownPolicy'],
getPreferences: [],
getFieldsMetadata: [],
canCreateEnrichPolicy: [],
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ export const QueryBarTopRow = React.memo(
docLinks,
http,
dataViews,
application,
} = kibana.services;

const isQueryLangSelected = props.query && !isOfQueryType(props.query);
Expand Down Expand Up @@ -745,6 +746,7 @@ export const QueryBarTopRow = React.memo(
hideRunQueryText={true}
data-test-subj="unifiedTextLangEditor"
isLoading={props.isLoading}
canCreateEnrichPolicy={!!application.capabilities.index_management?.manageEnrich}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that we need to add this property every time we want to reuse the editor. No need of an extra property imho, just move this flag inside the esql_editor.tsx

Everything else seems reasonable 🙌

/>
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ function wrapSearchBarInContext(testProps: any) {
theme: startMock.theme,
docLinks: startMock.docLinks,
storage: createMockStorage(),
application: {
capabilities: { index_management: { manageEnrich: true } },
},
data: {
query: {
savedQueries: {
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/index_management/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export class IndexMgmtServerPlugin implements Plugin<IndexManagementPluginSetup,
data: ['index_management'],
},
privileges: [
{
requiredClusterPrivileges: ['manage_enrich'],
ui: ['manageEnrich'],
},
{
// manage_index_templates is also required, but we will disable specific parts of the
// UI if this privilege is missing.
Expand Down