Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
9d6714b
Add Query Rules Detail Page with Draggable list
efegurkan Apr 10, 2025
911b860
Add some unit test coverage
efegurkan Apr 11, 2025
4508d34
Merge branch 'main' of github.com:elastic/kibana into query-rules-det…
efegurkan Apr 14, 2025
db3de31
Review changes
efegurkan Apr 23, 2025
064b5d0
Add custom heading element to draggable list
efegurkan Apr 23, 2025
3819a0f
Merge branch 'main' of github.com:elastic/kibana into query-rules-det…
efegurkan Apr 23, 2025
39dcc10
Review changes
efegurkan Apr 25, 2025
e6bc496
Merge branch 'main' of github.com:elastic/kibana into tmp/query-rule-…
efegurkan Apr 25, 2025
1fee4cc
Add metadata editor basics
efegurkan May 7, 2025
4d59722
Merge branch 'main' of github.com:elastic/kibana into tmp/query-rule-…
efegurkan May 7, 2025
9c65289
WIP
efegurkan May 12, 2025
fb614a3
Fixed rendering update issue and updated metadata editor
efegurkan May 21, 2025
b89446e
Add a flyout tests and remove extra files
efegurkan May 22, 2025
1fb47c5
Merge branch 'main' of github.com:elastic/kibana into query-rule-flyout
efegurkan May 22, 2025
bc2b4a2
Merge branch 'main' into query-rule-flyout
elasticmachine May 23, 2025
d5b8a1b
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine May 23, 2025
e37d4a1
Review changes
efegurkan May 29, 2025
1deb5a4
Merge branch 'main' of github.com:elastic/kibana into query-rule-flyout
efegurkan May 29, 2025
534465b
Fix issues created by wrongfully merged button
efegurkan May 29, 2025
626518a
Fix type errors
efegurkan May 29, 2025
55c00cc
Merge branch 'main' of github.com:elastic/kibana into query-rule-flyout
efegurkan Jun 1, 2025
0a2b96b
Add query rule document editor.
efegurkan May 29, 2025
9779f01
Merge branch 'main' of github.com:elastic/kibana into query-flyout-do…
efegurkan Jun 4, 2025
121b4f2
Add put handler in save button
efegurkan Jun 4, 2025
8a43a89
i18n fixes
efegurkan Jun 4, 2025
d331ce5
Fix save button and unintentional save of arrayField ids
efegurkan Jun 4, 2025
5d09c57
Removing comment
JoseLuisGJ Jun 4, 2025
e4175b7
Make body nullable
efegurkan Jun 4, 2025
f84bb48
Fixing tooltip content
JoseLuisGJ Jun 5, 2025
ab3dd2a
Disabling failing test
JoseLuisGJ Jun 5, 2025
643f5c5
Deleting rules is reactive
JoseLuisGJ Jun 5, 2025
b22bce7
Fixing Tour component steps
JoseLuisGJ Jun 5, 2025
db284ef
Skipping failing test
JoseLuisGJ Jun 6, 2025
504d1ec
Refetching queryRulesData every 1 second
JoseLuisGJ Jun 6, 2025
3835d11
Merge branch 'main' into query-flyout-document-selector
elasticmachine Jun 6, 2025
f97cb40
Pinned Callout UX improvement
JoseLuisGJ Jun 6, 2025
730d25f
isFormDirty management and Save disable
JoseLuisGJ Jun 9, 2025
53c2468
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 9, 2025
b11e701
Merge branch 'main' into query-flyout-document-selector
elasticmachine Jun 9, 2025
5ba3a06
Find your documents IDs into Discover
JoseLuisGJ Jun 9, 2025
82dc81f
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Jun 9, 2025
25f881d
Fixing test
JoseLuisGJ Jun 9, 2025
816b914
Criteria Callout
JoseLuisGJ Jun 10, 2025
81fdba2
Rule id tooltip
JoseLuisGJ Jun 10, 2025
d2a36fa
Consistent API links
JoseLuisGJ Jun 10, 2025
7b8d157
Document selector drag disabled when Excluding
JoseLuisGJ Jun 10, 2025
dd7582e
Rule header list responsive
JoseLuisGJ Jun 10, 2025
7a0efef
Adding better placeholders
JoseLuisGJ Jun 10, 2025
805c3ee
Enhance button behavior and messaging based on action fields presence…
JoseLuisGJ Jun 11, 2025
9d78e80
Empty state copy content review
JoseLuisGJ Jun 11, 2025
e5df2f0
Review changes
efegurkan Jun 11, 2025
1fd4e5e
Merge branch 'query-flyout-document-selector' of github.com:efegurkan…
efegurkan Jun 11, 2025
ff6f6f2
Merge branch 'main' into query-flyout-document-selector
elasticmachine Jun 11, 2025
ffb494c
review changes
efegurkan Jun 12, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

import React from 'react';

import { EuiLink, EuiButton, EuiButtonEmpty, EuiContextMenuItem } from '@elastic/eui';
import {
EuiLink,
EuiButton,
EuiButtonEmpty,
EuiContextMenuItem,
EuiButtonColor,
} from '@elastic/eui';
import { css } from '@emotion/react';
import type { ApplicationStart } from '@kbn/core-application-browser';
import type { SharePluginStart } from '@kbn/share-plugin/public';
Expand All @@ -28,6 +34,7 @@ export interface TryInConsoleButtonProps {
consolePlugin?: ConsolePluginStart;
sharePlugin?: SharePluginStart;
content?: string | React.ReactElement;
color?: EuiButtonColor;
showIcon?: boolean;
iconType?: string;
type?: 'link' | 'button' | 'emptyButton' | 'contextMenuItem';
Expand All @@ -41,6 +48,7 @@ export const TryInConsoleButton = ({
consolePlugin,
sharePlugin,
content = RUN_IN_CONSOLE,
color,
showIcon = true,
iconType = 'console',
type = 'emptyButton',
Expand Down Expand Up @@ -127,7 +135,7 @@ export const TryInConsoleButton = ({
case 'emptyButton':
default:
return (
<EuiButtonEmpty iconType={btnIconType} size="s" {...commonProps}>
<EuiButtonEmpty iconType={btnIconType} color={color} size="s" {...commonProps}>
{content}
</EuiButtonEmpty>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';

import {
EuiButtonIcon,
EuiComboBox,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
EuiHorizontalRule,
EuiIcon,
EuiLoadingSpinner,
EuiSplitPanel,
EuiText,
} from '@elastic/eui';
import { debounce } from 'lodash';
import { i18n } from '@kbn/i18n';
import { ResultFieldProps } from './result_types';
import { ResultFields } from './results_fields';

export interface EditableResultProps {
leftSideItem?: React.ReactNode;
hasIndexSelector?: boolean;
onDeleteDocument: () => void;
onIndexSelectorChange?: (index: string) => void;
onIdSelectorChange?: (id: string) => void;
onExpand?: () => void;
fields?: ResultFieldProps[];
indices?: string[];
initialDocId?: string;
initialIndex?: string;
error?: string;
isLoading?: boolean;
}

export const EditableResult: React.FC<EditableResultProps> = ({
leftSideItem,
hasIndexSelector,
onIndexSelectorChange,
onIdSelectorChange,
onDeleteDocument,
onExpand,
indices = [],
fields = [],
initialDocId = '',
initialIndex = '',
error,
isLoading = false,
}) => {
const [isExpanded, setIsExpanded] = React.useState(false);
const [documentId, setDocumentId] = React.useState(initialDocId);
const [index, setIndex] = React.useState(initialIndex);
return (
<EuiSplitPanel.Outer hasBorder={true}>
<EuiSplitPanel.Inner paddingSize="s" color="plain">
<EuiFlexGroup gutterSize="s" alignItems="center">
{leftSideItem && <EuiFlexItem grow={false}>{leftSideItem}</EuiFlexItem>}
<EuiFlexItem>
<EuiFlexGroup>
<EuiFlexItem>
<EuiFieldText
data-test-subj="editableResultDocumentId"
value={documentId}
onChange={(e) => setDocumentId(e.target.value)}
onBlur={(e) => {
if (onIdSelectorChange) {
onIdSelectorChange(e.target.value);
}
}}
fullWidth
placeholder={i18n.translate(
'xpack.sharedKbnSearchIndexDocuments.editableResult.documentIdPlaceholder',
{
defaultMessage: 'Document ID',
}
)}
/>
</EuiFlexItem>
{hasIndexSelector && (
<EuiFlexItem grow={false}>
<EuiComboBox
data-test-subj="editableResultIndexSelector"
placeholder={i18n.translate(
'xpack.sharedKbnSearchIndexDocuments.editableResult.selectIndexPlaceholder',
{
defaultMessage: 'Select index',
}
)}
singleSelection={{ asPlainText: true }}
options={indices.map((i) => ({ label: i, value: 'index' }))}
isClearable={false}
selectedOptions={index ? [{ label: index, value: 'index' }] : []}
onChange={(selected) => {
const selectedIndex = selected[0]?.label || '';
setIndex(selectedIndex);
if (onIndexSelectorChange) {
debounce(() => {
onIndexSelectorChange(selectedIndex);
}, 300)();
}
}}
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup
gutterSize="s"
alignItems="center"
justifyContent="flexEnd"
responsive={false}
>
<EuiFlexItem grow={false}>
{error && <EuiIcon type="warning" color="danger" />}
{!error &&
hasIndexSelector &&
(isLoading ? (
<EuiLoadingSpinner />
) : (
<EuiButtonIcon
size="xs"
iconType={isExpanded ? 'fold' : 'unfold'}
color="primary"
aria-label={isExpanded ? 'Collapse fields' : 'Expand fields'}
onClick={() => {
if (onExpand && !isExpanded) {
onExpand();
}
setIsExpanded(!isExpanded);
}}
/>
))}
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonIcon
iconType="trash"
color="danger"
onClick={onDeleteDocument}
aria-label="Delete document"
data-test-subj="editableResultDeleteButton"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiSplitPanel.Inner>
{!error && fields?.length > 0 && isExpanded && (
<>
<EuiHorizontalRule margin="none" />
<EuiSplitPanel.Inner paddingSize="s" color="plain">
<ResultFields documentId="12345" isExpanded={false} fields={fields} />
</EuiSplitPanel.Inner>
</>
)}
{error && (
<EuiSplitPanel.Inner paddingSize="s" color="danger">
<EuiFlexGroup alignItems="center" gutterSize="s">
<EuiFlexItem grow={false}>
<EuiText color="danger" size="xs">
<EuiIcon type="warning" />
&nbsp;
{error}
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiSplitPanel.Inner>
)}
</EuiSplitPanel.Outer>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export {
resultToFieldFromMappings as resultToField,
reorderFieldsInImportance,
} from './result_metadata';
export { EditableResult } from './editable_result';
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ export enum APIRoutes {
QUERY_RULES_SETS = '/internal/search_query_rules/query_rules_sets',
QUERY_RULES_QUERY_RULE_FETCH = '/internal/search_query_rules/ruleset/{ruleset_id}/rule/{rule_id}',
QUERY_RULES_RULESET_ID = '/internal/search_query_rules/ruleset/{ruleset_id}',
FETCH_INDICES = '/internal/search_query_rules/indices',
FETCH_DOCUMENT = '/internal/search_query_rules/document/{indexName}/{documentId}',
GENERATE_RULE_ID = '/internal/search_query_rules/ruleset/{rulesetId}/generate_rule_id',
QUERY_RULES_RULESET_RULE = '/internal/search_query_rules/ruleset/{ruleset_id}/rule/{rule_id}',
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/

import {
GetResponse,
IndicesGetMappingResponse,
QueryRulesQueryRule,
QueryRulesQueryRuleCriteria,
QueryRulesQueryRuleset,
Expand Down Expand Up @@ -33,6 +35,11 @@ export type SearchQueryRulesQueryRuleset = Omit<QueryRulesQueryRuleset, 'rules'>
rules: SearchQueryRulesQueryRule[];
};

export interface SearchQueryDocumentResponse {
document: GetResponse<unknown>;
mappings: IndicesGetMappingResponse;
}

export type QueryRuleEditorForm = Pick<
SearchQueryRulesQueryRule,
'criteria' | 'type' | 'actions'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const EmptyPrompt: React.FC<EmptyPromptProps> = ({ getStartedAction }) =>
<h2>
<FormattedMessage
id="xpack.queryRules.emptyPrompt.title"
defaultMessage="Improve your search experience with targeted business logic"
defaultMessage="Add custom business logic with query rules"
/>
</h2>
</EuiTitle>
Expand All @@ -88,7 +88,7 @@ export const EmptyPrompt: React.FC<EmptyPromptProps> = ({ getStartedAction }) =>
<p>
<FormattedMessage
id="xpack.queryRules.emptyPrompt.subtitle"
defaultMessage="Add business logic to your queries to get customized results under different conditions."
defaultMessage="Enhance search experiences with custom rules to filter and prioritize results based on your business logic."
/>
</p>
</EuiText>
Expand Down Expand Up @@ -248,7 +248,7 @@ export const EmptyPrompt: React.FC<EmptyPromptProps> = ({ getStartedAction }) =>
>
<FormattedMessage
id="xpack.queryRules.emptyPrompt.footerLink"
defaultMessage="Query Rules API documentation"
defaultMessage="API reference"
/>
</EuiLink>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
* 2.0.
*/

import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';

import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
import {
EuiButton,
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiLink,
EuiLoadingSpinner,
EuiText,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import { docLinks } from '../../../common/doc_links';
import { useFetchQueryRulesSets } from '../../hooks/use_fetch_query_rules_sets';
import { EmptyPrompt } from '../empty_prompt/empty_prompt';
Expand All @@ -30,7 +31,20 @@ import { CreateRulesetModal } from '../query_rules_sets/create_ruleset_modal';
import { QueryRulesPageTemplate } from '../../layout/query_rules_page_template';

export const QueryRulesOverview = () => {
const { data: queryRulesData, isInitialLoading, isError, error } = useFetchQueryRulesSets();
const {
data: queryRulesData,
isInitialLoading,
isError,
error,
refetch,
} = useFetchQueryRulesSets();

useEffect(() => {
const interval = setInterval(() => {
refetch();
}, 1000);
return () => clearInterval(interval);
}, [refetch]);
const [isCreateModalVisible, setIsCreateModalVisible] = useState(false);
const backgroundProps = css({
backgroundImage: `url(${queryRulesBackground})`,
Expand All @@ -52,17 +66,23 @@ export const QueryRulesOverview = () => {
rightSideItems={[
<EuiFlexGroup alignItems="center" key="queryRulesOverviewHeaderButtons">
<EuiFlexItem grow={false}>
<EuiLink
data-test-subj="queryRulesOverviewApiDocumentationLink"
external
target="_blank"
<EuiButtonEmpty
data-test-subj="queryRulesetDetailApiReferenceButton"
iconType="documentation"
color="text"
aria-label={i18n.translate(
'xpack.queryRules.queryRulesetDetail.apiReferenceButton',
{
defaultMessage: 'API reference',
}
)}
href={docLinks.queryRulesApi}
target="_blank"
>
<FormattedMessage
id="xpack.queryRules.queryRulesSetDetail.documentationLink"
defaultMessage="API Documentation"
/>
</EuiLink>
{i18n.translate('xpack.queryRules.queryRulesetDetail.apiReferenceButton', {
defaultMessage: 'API reference',
})}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
Expand Down
Loading