Skip to content

Commit

Permalink
[8.x] [Automatic Import] Fix the enter bug (#199894) (#203817)
Browse files Browse the repository at this point in the history
# Backport

This will backport the following commits from `main` to `8.x`:
- [[Automatic Import] Fix the enter bug
(#199894)](#199894)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Ilya
Nikokoshev","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-11T15:04:45Z","message":"[Automatic
Import] Fix the enter bug (#199894)\n\n## Release Notes\r\n\r\nFixes the
bug where pressing Enter reloaded the Automatic Import.\r\n\r\n##
Summary\r\n\r\n- Fixes #198238\r\n- Adds/fixes telemetry for CEL
events.\r\n- Refactors navigation functionality.\r\n- Adds extensive
unit tests and a Cypress test for it.\r\n\r\n## Details\r\n\r\nWhen the
user presses the Enter inside our input field, the expected\r\naction is
to send the form, in this case completing the step.
However,\r\npreviously the form submission would instead lead to
reloading the whole\r\nAutomatic Import page.\r\n\r\nIn this PR we
capture the form submission event and bubble it up as\r\n`completeStep`
to the main component. We also move the implementation\r\nfrom the
`Footer` up to this main component\r\n`CreateIntegrationAssistant`. This
helps collect all the details about\r\nthe step order in one place and
refactor this logic.\r\n\r\nAs a result, pressing `Enter` in any field
now either\r\n - Is processed by the field itself (in case of multi-line
fields);\r\n- Leads to the same action as pressing the \"Next\" button
(desired\r\nresult); or\r\n- Does nothing (e.g. in the inputs in the
\"Define data stream and upload\r\nlogs\" group – the reason for this is
unclear).\r\n\r\nWe add CEL-specific telemetry identifiers so that
telemetry for step 5\r\nis not always reported as `Deploy
Step`.\r\n\r\nWe also rename a bunch of stuff that was named
`...StepReady` into\r\n`...StepReadyToComplete` as the previous name was
ambiguous. To\r\ndemonstrate this ambiguity we've enlisted the help of
GPT 4o:\r\n\r\n<img width=\"832\"
alt=\"SCR-20241125-tiaa\"\r\nsrc=\"https://github.com/user-attachments/assets/ad6bcf7c-7cb2-41c2-ac6b-38924ce990d3\">\r\n\r\n\r\n##
Testing\r\n\r\nWe provide a Cypress test for Enter behavior: pressing it
on the\r\n\"integration title\" input should let the flow proceed to the
next step.\r\nThis test fails on `main`.\r\n\r\nWe also provide unit
tests for all steps of navigation functionality
in\r\n`x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.test.tsx`:\r\n\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"d8bb72ebfdb1514f1fc03857d4c4e02f70fb7403","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:fix","refactoring","Team:Fleet","v9.0.0","accessibility:
keyboard
navigation","backport:prev-minor","Team:Security-Scalability","Feature:AutomaticImport"],"title":"[Automatic
Import] Fix the enter
bug","number":199894,"url":"https://github.com/elastic/kibana/pull/199894","mergeCommit":{"message":"[Automatic
Import] Fix the enter bug (#199894)\n\n## Release Notes\r\n\r\nFixes the
bug where pressing Enter reloaded the Automatic Import.\r\n\r\n##
Summary\r\n\r\n- Fixes #198238\r\n- Adds/fixes telemetry for CEL
events.\r\n- Refactors navigation functionality.\r\n- Adds extensive
unit tests and a Cypress test for it.\r\n\r\n## Details\r\n\r\nWhen the
user presses the Enter inside our input field, the expected\r\naction is
to send the form, in this case completing the step.
However,\r\npreviously the form submission would instead lead to
reloading the whole\r\nAutomatic Import page.\r\n\r\nIn this PR we
capture the form submission event and bubble it up as\r\n`completeStep`
to the main component. We also move the implementation\r\nfrom the
`Footer` up to this main component\r\n`CreateIntegrationAssistant`. This
helps collect all the details about\r\nthe step order in one place and
refactor this logic.\r\n\r\nAs a result, pressing `Enter` in any field
now either\r\n - Is processed by the field itself (in case of multi-line
fields);\r\n- Leads to the same action as pressing the \"Next\" button
(desired\r\nresult); or\r\n- Does nothing (e.g. in the inputs in the
\"Define data stream and upload\r\nlogs\" group – the reason for this is
unclear).\r\n\r\nWe add CEL-specific telemetry identifiers so that
telemetry for step 5\r\nis not always reported as `Deploy
Step`.\r\n\r\nWe also rename a bunch of stuff that was named
`...StepReady` into\r\n`...StepReadyToComplete` as the previous name was
ambiguous. To\r\ndemonstrate this ambiguity we've enlisted the help of
GPT 4o:\r\n\r\n<img width=\"832\"
alt=\"SCR-20241125-tiaa\"\r\nsrc=\"https://github.com/user-attachments/assets/ad6bcf7c-7cb2-41c2-ac6b-38924ce990d3\">\r\n\r\n\r\n##
Testing\r\n\r\nWe provide a Cypress test for Enter behavior: pressing it
on the\r\n\"integration title\" input should let the flow proceed to the
next step.\r\nThis test fails on `main`.\r\n\r\nWe also provide unit
tests for all steps of navigation functionality
in\r\n`x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.test.tsx`:\r\n\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"d8bb72ebfdb1514f1fc03857d4c4e02f70fb7403"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/199894","number":199894,"mergeCommit":{"message":"[Automatic
Import] Fix the enter bug (#199894)\n\n## Release Notes\r\n\r\nFixes the
bug where pressing Enter reloaded the Automatic Import.\r\n\r\n##
Summary\r\n\r\n- Fixes #198238\r\n- Adds/fixes telemetry for CEL
events.\r\n- Refactors navigation functionality.\r\n- Adds extensive
unit tests and a Cypress test for it.\r\n\r\n## Details\r\n\r\nWhen the
user presses the Enter inside our input field, the expected\r\naction is
to send the form, in this case completing the step.
However,\r\npreviously the form submission would instead lead to
reloading the whole\r\nAutomatic Import page.\r\n\r\nIn this PR we
capture the form submission event and bubble it up as\r\n`completeStep`
to the main component. We also move the implementation\r\nfrom the
`Footer` up to this main component\r\n`CreateIntegrationAssistant`. This
helps collect all the details about\r\nthe step order in one place and
refactor this logic.\r\n\r\nAs a result, pressing `Enter` in any field
now either\r\n - Is processed by the field itself (in case of multi-line
fields);\r\n- Leads to the same action as pressing the \"Next\" button
(desired\r\nresult); or\r\n- Does nothing (e.g. in the inputs in the
\"Define data stream and upload\r\nlogs\" group – the reason for this is
unclear).\r\n\r\nWe add CEL-specific telemetry identifiers so that
telemetry for step 5\r\nis not always reported as `Deploy
Step`.\r\n\r\nWe also rename a bunch of stuff that was named
`...StepReady` into\r\n`...StepReadyToComplete` as the previous name was
ambiguous. To\r\ndemonstrate this ambiguity we've enlisted the help of
GPT 4o:\r\n\r\n<img width=\"832\"
alt=\"SCR-20241125-tiaa\"\r\nsrc=\"https://github.com/user-attachments/assets/ad6bcf7c-7cb2-41c2-ac6b-38924ce990d3\">\r\n\r\n\r\n##
Testing\r\n\r\nWe provide a Cypress test for Enter behavior: pressing it
on the\r\n\"integration title\" input should let the flow proceed to the
next step.\r\nThis test fails on `main`.\r\n\r\nWe also provide unit
tests for all steps of navigation functionality
in\r\n`x-pack/plugins/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.test.tsx`:\r\n\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"d8bb72ebfdb1514f1fc03857d4c4e02f70fb7403"}}]}]
BACKPORT-->

Co-authored-by: Ilya Nikokoshev <[email protected]>
  • Loading branch information
kibanamachine and ilyannn authored Dec 11, 2024
1 parent f1b475d commit 0cf7aa3
Show file tree
Hide file tree
Showing 19 changed files with 976 additions and 495 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,96 @@
* 2.0.
*/

import React, { useReducer, useMemo, useEffect } from 'react';
import React, { useReducer, useMemo, useEffect, useCallback } from 'react';
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
import { Header } from './header';
import { Footer } from './footer';
import { ConnectorStep, isConnectorStepReady } from './steps/connector_step';
import { IntegrationStep, isIntegrationStepReady } from './steps/integration_step';
import { DataStreamStep, isDataStreamStepReady } from './steps/data_stream_step';
import { ReviewStep, isReviewStepReady } from './steps/review_step';
import { CelInputStep, isCelInputStepReady } from './steps/cel_input_step';
import { ReviewCelStep, isCelReviewStepReady } from './steps/review_cel_step';
import { useNavigate, Page } from '../../../common/hooks/use_navigate';
import { ConnectorStep, isConnectorStepReadyToComplete } from './steps/connector_step';
import { IntegrationStep, isIntegrationStepReadyToComplete } from './steps/integration_step';
import { DataStreamStep, isDataStreamStepReadyToComplete } from './steps/data_stream_step';
import { ReviewStep, isReviewStepReadyToComplete } from './steps/review_step';
import { CelInputStep, isCelInputStepReadyToComplete } from './steps/cel_input_step';
import { ReviewCelStep, isCelReviewStepReadyToComplete } from './steps/review_cel_step';
import { DeployStep } from './steps/deploy_step';
import { reducer, initialState, ActionsProvider, type Actions } from './state';
import { useTelemetry } from '../telemetry';
import { ExperimentalFeaturesService } from '../../../services';

const stepNames: Record<number | string, string> = {
1: 'Connector Step',
2: 'Integration Step',
3: 'DataStream Step',
4: 'Review Step',
cel_input: 'CEL Input Step',
cel_review: 'CEL Review Step',
deploy: 'Deploy Step',
};

export const CreateIntegrationAssistant = React.memo(() => {
const [state, dispatch] = useReducer(reducer, initialState);

const navigate = useNavigate();
const { generateCel: isGenerateCelEnabled } = ExperimentalFeaturesService.get();

const celInputStepIndex = isGenerateCelEnabled && state.hasCelInput ? 5 : null;
const celReviewStepIndex = isGenerateCelEnabled && state.celInputResult ? 6 : null;
const deployStepIndex =
celInputStepIndex !== null || celReviewStepIndex !== null || state.step === 7 ? 7 : 5;

const stepName =
state.step === deployStepIndex
? stepNames.deploy
: state.step === celReviewStepIndex
? stepNames.cel_review
: state.step === celInputStepIndex
? stepNames.cel_input
: state.step in stepNames
? stepNames[state.step]
: 'Unknown Step';

const telemetry = useTelemetry();
useEffect(() => {
telemetry.reportAssistantOpen();
}, [telemetry]);

const isThisStepReadyToComplete = useMemo(() => {
if (state.step === 1) {
return isConnectorStepReadyToComplete(state);
} else if (state.step === 2) {
return isIntegrationStepReadyToComplete(state);
} else if (state.step === 3) {
return isDataStreamStepReadyToComplete(state);
} else if (state.step === 4) {
return isReviewStepReadyToComplete(state);
} else if (isGenerateCelEnabled && state.step === 5) {
return isCelInputStepReadyToComplete(state);
} else if (isGenerateCelEnabled && state.step === 6) {
return isCelReviewStepReadyToComplete(state);
}
return false;
}, [state, isGenerateCelEnabled]);

const goBackStep = useCallback(() => {
if (state.step === 1) {
navigate(Page.landing);
} else {
dispatch({ type: 'SET_STEP', payload: state.step - 1 });
}
}, [navigate, dispatch, state.step]);

const completeStep = useCallback(() => {
if (!isThisStepReadyToComplete) {
// If the user tries to navigate to the next step without completing the current step.
return;
}
telemetry.reportAssistantStepComplete({ step: state.step, stepName });
if (state.step === 3 || state.step === celInputStepIndex) {
dispatch({ type: 'SET_IS_GENERATING', payload: true });
} else {
dispatch({ type: 'SET_STEP', payload: state.step + 1 });
}
}, [telemetry, state.step, stepName, celInputStepIndex, isThisStepReadyToComplete]);

const actions = useMemo<Actions>(
() => ({
setStep: (payload) => {
Expand All @@ -53,27 +118,11 @@ export const CreateIntegrationAssistant = React.memo(() => {
setCelInputResult: (payload) => {
dispatch({ type: 'SET_CEL_INPUT_RESULT', payload });
},
completeStep,
}),
[]
[completeStep]
);

const isNextStepEnabled = useMemo(() => {
if (state.step === 1) {
return isConnectorStepReady(state);
} else if (state.step === 2) {
return isIntegrationStepReady(state);
} else if (state.step === 3) {
return isDataStreamStepReady(state);
} else if (state.step === 4) {
return isReviewStepReady(state);
} else if (isGenerateCelEnabled && state.step === 5) {
return isCelInputStepReady(state);
} else if (isGenerateCelEnabled && state.step === 6) {
return isCelReviewStepReady(state);
}
return false;
}, [state, isGenerateCelEnabled]);

return (
<ActionsProvider value={actions}>
<KibanaPageTemplate>
Expand All @@ -95,28 +144,21 @@ export const CreateIntegrationAssistant = React.memo(() => {
result={state.result}
/>
)}
{state.step === 5 &&
(isGenerateCelEnabled && state.hasCelInput ? (
<CelInputStep
integrationSettings={state.integrationSettings}
connector={state.connector}
isGenerating={state.isGenerating}
/>
) : (
<DeployStep
integrationSettings={state.integrationSettings}
result={state.result}
connector={state.connector}
/>
))}

{isGenerateCelEnabled && state.celInputResult && state.step === 6 && (
{state.step === celInputStepIndex && (
<CelInputStep
integrationSettings={state.integrationSettings}
connector={state.connector}
isGenerating={state.isGenerating}
/>
)}
{state.step === celReviewStepIndex && (
<ReviewCelStep
isGenerating={state.isGenerating}
celInputResult={state.celInputResult}
/>
)}
{isGenerateCelEnabled && state.step === 7 && (

{state.step === deployStepIndex && (
<DeployStep
integrationSettings={state.integrationSettings}
result={state.result}
Expand All @@ -126,10 +168,14 @@ export const CreateIntegrationAssistant = React.memo(() => {
)}
</KibanaPageTemplate.Section>
<Footer
currentStep={state.step}
isGenerating={state.isGenerating}
hasCelInput={state.hasCelInput}
isNextStepEnabled={isNextStepEnabled}
isAnalyzeStep={state.step === 3}
isAnalyzeCelStep={state.step === celInputStepIndex}
isLastStep={state.step === deployStepIndex}
isNextStepEnabled={isThisStepReadyToComplete && !state.isGenerating}
isNextAddingToElastic={state.step === deployStepIndex - 1}
onBack={goBackStep}
onNext={completeStep}
/>
</KibanaPageTemplate>
</ActionsProvider>
Expand Down
Loading

0 comments on commit 0cf7aa3

Please sign in to comment.