Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,6 @@ export const SEARCH_PLACEHOLDER = i18n.translate(
}
);

export const MANUAL_TRIGGERS_DESCRIPTIONS: Record<string, string> = {
manual: i18n.translate(
'plugins.workflowsManagement.workflowsExecution.manualTriggerDescription',
{
defaultMessage:
'Provide custom JSON data manually for testing. Ideal for simulating specific scenarios or debugging edge cases.',
}
),
index: i18n.translate('plugins.workflowsManagement.workflowsExecution.indexTriggerDescription', {
defaultMessage:
'Choose a document directly from an index to use as the test input. This is helpful for verifying workflows against real indexed data.',
}),
alert: i18n.translate('plugins.workflowsManagement.workflowsExecution.alertTriggerDescription', {
defaultMessage:
'Choose an existing alert directly from an index to use as the test input. This is helpful for verifying workflows against real alerts data.',
}),
scheduled: i18n.translate(
'plugins.workflowsManagement.workflowsExecution.scheduledTriggerDescription',
{
defaultMessage: 'Select a schedule to trigger workflow',
}
),
};

export const TRIGGERS_LIST_TITLE = i18n.translate(
'plugins.workflowsManagement.workflowsList.triggersListTitle',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ const workflowTestRunInitiatedSchema: RootSchema<ReportWorkflowTestRunInitiatedA
triggerTab: {
type: 'keyword',
_meta: {
description: 'The trigger tab selected in the Test Workflow modal: manual, alert, or index',
description:
'The trigger tab selected in the Test Workflow modal: manual, alert, index, or historical',
optional: true,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import type { WorkflowTriggerTab } from '../../../../../../features/run_workflow/ui/types';
import type { BaseResultActionParams, WorkflowEditorType } from '../types';

export enum WorkflowExecutionEventTypes {
Expand All @@ -32,13 +33,6 @@ export enum WorkflowExecutionEventTypes {
WorkflowRunCancelled = 'workflows_workflow_run_cancelled',
}

export type WorkflowTriggerType = 'manual' | 'alert' | 'scheduled';

/**
* Trigger tab types available in the Test Workflow modal
*/
export type WorkflowTriggerTab = 'manual' | 'alert' | 'index';

/**
* Parameters for workflow test run initiation telemetry.
*/
Expand All @@ -61,7 +55,7 @@ export interface ReportWorkflowTestRunInitiatedActionParams extends BaseResultAc
*/
editorType?: WorkflowEditorType;
/**
* The trigger tab selected in the Test Workflow modal: 'manual', 'alert', or 'index'
* The trigger tab selected in the Test Workflow modal
*/
triggerTab?: WorkflowTriggerTab;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

import type { WorkflowYaml } from '@kbn/workflows/spec/schema';
import type { WorkflowTriggerTab } from '../../features/run_workflow/ui/types';
import type { YamlValidationResult } from '../../features/validate_workflow_yaml/model/types';
import {
workflowEventNames,
Expand All @@ -16,7 +17,6 @@ import {
WorkflowUIEventTypes,
WorkflowValidationEventTypes,
} from '../lib/telemetry/events/workflows';
import type { WorkflowTriggerTab } from '../lib/telemetry/events/workflows/execution/types';
import type {
WorkflowEditorType,
WorkflowTelemetryOrigin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
WorkflowDetailDto,
WorkflowListDto,
} from '@kbn/workflows';
import type { WorkflowTriggerTab } from '../../../features/run_workflow/ui/types';
import { useKibana } from '../../../hooks/use_kibana';
import { useTelemetry } from '../../../hooks/use_telemetry';

Expand Down Expand Up @@ -223,7 +224,7 @@ export function useWorkflowActions() {
const runWorkflow = useMutation<
RunWorkflowResponseDto,
HttpError,
RunWorkflowCommand & { id: string; triggerTab?: 'manual' | 'alert' | 'index' }
RunWorkflowCommand & { id: string; triggerTab?: WorkflowTriggerTab }
>({
mutationKey: ['POST', 'workflows', 'id', 'run'],
mutationFn: ({ id, inputs }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { useQuery } from '@kbn/react-query';
import type { WorkflowExecutionDto } from '@kbn/workflows';
import { useKibana } from '../../../hooks/use_kibana';

interface UseWorkflowExecutionParams {
executionId: string | null;
enabled?: boolean;
}

export function useWorkflowExecution({ executionId, enabled = true }: UseWorkflowExecutionParams) {
const { http } = useKibana().services;

return useQuery<WorkflowExecutionDto | null>({
queryKey: ['workflowExecution', executionId],
queryFn: async () => {
if (!executionId) return null;
const response = await http.get<WorkflowExecutionDto>(
`/api/workflowExecutions/${executionId}`
);
return response;
},
enabled: enabled && executionId !== null,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ export const selectWorkflowDefinition = createSelector(
);

// Only checks if the current workflow yaml can be parsed, does not check the schema, only the yaml syntax
export const selectIsYamlSyntaxValid = createSelector(selectYamlComputed, (computed): boolean =>
Boolean(computed?.workflowDefinition)
export const selectIsYamlSyntaxValid = createSelector(selectYamlDocument, (yamlDoc): boolean =>
Boolean(yamlDoc && yamlDoc.errors.length === 0)
);

// Checks whether validation errors (from strict schema + custom validations) are present
Expand All @@ -74,6 +74,11 @@ export const selectIsTestModalOpen = createSelector(
(detail) => detail.isTestModalOpen
);

export const selectReplayExecutionId = createSelector(
selectDetail,
(detail) => detail.replayExecutionId
);

export const selectIsSavingYaml = createSelector(
selectDetail,
(detail) => detail.loading.isSavingYaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const initialState: WorkflowDetailState = {
focusedStepId: undefined,
highlightedStepId: undefined,
isTestModalOpen: false,
replayExecutionId: null,
loading: initialLoadingState,
hasYamlSchemaValidationErrors: false,
connectorFlyout: {
Expand Down Expand Up @@ -76,6 +77,9 @@ const workflowDetailSlice = createSlice({
setIsTestModalOpen: (state, action: { payload: boolean }) => {
state.isTestModalOpen = action.payload;
},
setReplayExecutionId: (state, action: { payload: string | null }) => {
state.replayExecutionId = action.payload;
},
setConnectors: (state, action: { payload: WorkflowDetailState['connectors'] }) => {
state.connectors = action.payload;
},
Expand Down Expand Up @@ -152,6 +156,7 @@ export const {
setCursorPosition,
setHighlightedStepId,
setIsTestModalOpen,
setReplayExecutionId,
setConnectors,
setExecution,
clearExecution,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import { i18n } from '@kbn/i18n';
import { WorkflowsBaseTelemetry } from '../../../../../common/service/telemetry';
import type { WorkflowTriggerTab } from '../../../../../features/run_workflow/ui/types';
import type { WorkflowsServices } from '../../../../../types';
import type { RootState } from '../../types';
import { selectWorkflow, selectYamlString } from '../selectors';

export interface TestWorkflowParams {
inputs: Record<string, unknown>;
triggerTab?: 'manual' | 'alert' | 'index';
triggerTab?: WorkflowTriggerTab;
}

export interface TestWorkflowResponse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export interface WorkflowDetailState {
highlightedStepId?: string;
/** The modal to test the workflow is open */
isTestModalOpen: boolean;
/** When set, open test modal in "From historical" mode with this execution pre-selected */
replayExecutionId: string | null;
/** The connectors data */
connectors?: ConnectorsResponse;
/** The schema for the workflow, depends on the connectors available */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export const ENABLED_TRIGGER_TABS = ['alert', 'index', 'manual', 'historical'] as const;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { i18n } from '@kbn/i18n';
import type { WorkflowTriggerTab } from './types';

export const TRIGGER_TABS_LABELS: Record<WorkflowTriggerTab, string> = {
alert: i18n.translate('plugins.workflowsManagement.workflowsExecution.alertTriggerLabel', {
defaultMessage: 'Alert',
}),
index: i18n.translate('plugins.workflowsManagement.workflowsExecution.indexTriggerLabel', {
defaultMessage: 'Document',
}),
manual: i18n.translate('plugins.workflowsManagement.workflowsExecution.manualTriggerLabel', {
defaultMessage: 'Manual',
}),
historical: i18n.translate(
'plugins.workflowsManagement.workflowsExecution.historicalTriggerLabel',
{ defaultMessage: 'Historical' }
),
};

export const TRIGGER_TABS_DESCRIPTIONS: Record<WorkflowTriggerTab, string> = {
manual: i18n.translate(
'plugins.workflowsManagement.workflowsExecution.manualTriggerDescription',
{
defaultMessage: 'Provide custom JSON data manually.',
}
),
index: i18n.translate('plugins.workflowsManagement.workflowsExecution.indexTriggerDescription', {
defaultMessage: 'Choose a document from Elasticsearch.',
}),
alert: i18n.translate('plugins.workflowsManagement.workflowsExecution.alertTriggerDescription', {
defaultMessage: 'Choose an existing alert directly.',
}),
historical: i18n.translate(
'plugins.workflowsManagement.workflowsExecution.historicalTriggerDescription',
{ defaultMessage: 'Reuse input data from previous executions.' }
),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import type { ENABLED_TRIGGER_TABS } from './constants';

export type WorkflowTriggerTab = (typeof ENABLED_TRIGGER_TABS)[number];
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiLoadingSpinner,
EuiPanel,
EuiSpacer,
EuiText,
} from '@elastic/eui';
Expand Down Expand Up @@ -325,29 +326,31 @@ export const WorkflowExecuteEventForm = ({
<EuiFlexGroup direction="column" gutterSize="s">
<EuiSpacer size="s" />
<EuiFlexItem>
<AlertsSearchBar
appName="workflow_management"
showDatePicker
onQueryChange={handleQueryChange}
onQuerySubmit={handleQuerySubmit}
onFiltersUpdated={handleFiltersUpdated}
query={query}
filters={filters}
rangeFrom={timeRange.from}
rangeTo={timeRange.to}
showFilterBar={false}
showSubmitButton={true}
placeholder={i18n.translate('workflows.workflowExecuteEventForm.searchPlaceholder', {
defaultMessage:
'Filter your data using KQL syntax (e.g., rule.name:test or kibana.alert.rule.name:test)',
})}
ruleTypeIds={[]}
http={http}
toasts={notifications.toasts}
unifiedSearchBar={unifiedSearch.ui.SearchBar}
dataService={dataService}
fetchUnifiedAlertsFields={true}
/>
<EuiPanel paddingSize="s" hasBorder={false} hasShadow={false} color="transparent">
<AlertsSearchBar
appName="workflow_management"
showDatePicker
onQueryChange={handleQueryChange}
onQuerySubmit={handleQuerySubmit}
onFiltersUpdated={handleFiltersUpdated}
query={query}
filters={filters}
rangeFrom={timeRange.from}
rangeTo={timeRange.to}
showFilterBar={false}
showSubmitButton={true}
placeholder={i18n.translate('workflows.workflowExecuteEventForm.searchPlaceholder', {
defaultMessage:
'Filter your data using KQL syntax (e.g., rule.name:test or kibana.alert.rule.name:test)',
})}
ruleTypeIds={[]}
http={http}
toasts={notifications.toasts}
unifiedSearchBar={unifiedSearch.ui.SearchBar}
dataService={dataService}
fetchUnifiedAlertsFields={true}
/>
</EuiPanel>
</EuiFlexItem>
<EuiFlexItem>
{alertsLoading ? (
Expand Down
Loading
Loading