Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
636d34e
next buttons
stephmilovic Oct 28, 2022
c48c2ca
set initial value and expose submit function from getCreateCaseFlyout
stephmilovic Oct 28, 2022
50fddb9
Merge branch 'main' into guided_onboarding_design
stephmilovic Oct 31, 2022
a19b090
push
stephmilovic Oct 31, 2022
50fe19c
button focus
stephmilovic Oct 31, 2022
dea3873
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 1, 2022
095a436
fixing
stephmilovic Nov 1, 2022
b17c725
merge main
stephmilovic Nov 1, 2022
bbe2a1d
fix a couple tests
stephmilovic Nov 1, 2022
17e8c0e
fix
stephmilovic Nov 1, 2022
d1932bc
ok
stephmilovic Nov 1, 2022
bdc4cb4
useAddToCaseActions tests
stephmilovic Nov 1, 2022
810f0ea
make sure AlertsCasesTourSteps is used everywhere
stephmilovic Nov 1, 2022
b1d12e4
add tests to cases area
stephmilovic Nov 1, 2022
80ec3c1
rm comment
stephmilovic Nov 1, 2022
c969319
add import
stephmilovic Nov 1, 2022
47eb7e0
add test in cases
stephmilovic Nov 2, 2022
a134f3f
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 2, 2022
8a8333f
add fun markdown
stephmilovic Nov 2, 2022
37988ed
test fix
stephmilovic Nov 2, 2022
ad08ae6
Merge branch 'main' into guided_onboarding_design
kibanamachine Nov 2, 2022
6f4e9c3
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 2, 2022
afc9902
Merge branch 'guided_onboarding_design' of github.com:stephmilovic/ki…
stephmilovic Nov 2, 2022
f6b59ae
codeowners
stephmilovic Nov 2, 2022
5e24730
useMemo on context provider
stephmilovic Nov 2, 2022
f98b2ea
fix for mr michael
stephmilovic Nov 2, 2022
d854113
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 3, 2022
a1d439c
isSubmit to autoSubmit
stephmilovic Nov 3, 2022
aa83e89
autoSubmit to props
stephmilovic Nov 3, 2022
64aaf95
move bool
stephmilovic Nov 3, 2022
d0e8a42
fix keys
stephmilovic Nov 3, 2022
506da35
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 4, 2022
442f5ad
fix tests
stephmilovic Nov 4, 2022
6c22869
end tour on case details page
stephmilovic Nov 7, 2022
b2bf83d
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 7, 2022
1ba3eed
test fix
stephmilovic Nov 7, 2022
4b77eeb
more better
stephmilovic Nov 7, 2022
15740ac
better now
stephmilovic Nov 8, 2022
53f2228
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 8, 2022
fe6ef7b
finish tour on case details page vs onclick of the link
stephmilovic Nov 8, 2022
95403c2
revert submit callback in create case
stephmilovic Nov 8, 2022
6d04afb
revert more cases
stephmilovic Nov 8, 2022
1f821a4
test fix
stephmilovic Nov 8, 2022
0a26e9d
add tests
stephmilovic Nov 8, 2022
b26a7bc
fix side effects and tests
stephmilovic Nov 8, 2022
3dcb219
just a fix up
stephmilovic Nov 8, 2022
5f9c56d
adds tests for tour context in related_cases
stephmilovic Nov 8, 2022
3cc0718
data-test-subj to tour-step
stephmilovic Nov 8, 2022
3b91a69
tests for cases_tour_steps
stephmilovic Nov 8, 2022
2df8a1c
more test
stephmilovic Nov 8, 2022
02b28b1
pr fixes
stephmilovic Nov 9, 2022
c7615c6
fix type
stephmilovic Nov 9, 2022
92d0ac8
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 9, 2022
b37e65c
setStep function added and type fix
stephmilovic Nov 9, 2022
1a0c157
fix whoops
stephmilovic Nov 9, 2022
4156066
Merge branch 'main' into guided_onboarding_design
stephmilovic Nov 9, 2022
48b739a
fix test
stephmilovic Nov 9, 2022
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 @@ -66,6 +66,7 @@ describe('use cases add to existing case modal hook', () => {
externalReferenceAttachmentTypeRegistry,
persistableStateAttachmentTypeRegistry,
owner: ['test'],
isSubmit: false,
permissions: allCasesPermissions(),
appId: 'test',
appTitle: 'jest',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const getInitialCasesContextState = (): CasesContextState => {
return {
createCaseFlyout: {
isFlyoutOpen: false,
isSubmit: false,
},
selectCaseModal: {
isModalOpen: false,
Expand All @@ -23,6 +24,7 @@ export const getInitialCasesContextState = (): CasesContextState => {
export interface CasesContextState {
createCaseFlyout: {
isFlyoutOpen: boolean;
isSubmit: boolean;
props?: CreateCaseFlyoutProps;
};
selectCaseModal: {
Expand All @@ -36,6 +38,7 @@ export enum CasesContextStoreActionsList {
CLOSE_CREATE_CASE_FLYOUT,
OPEN_ADD_TO_CASE_MODAL,
CLOSE_ADD_TO_CASE_MODAL,
SUBMIT_CASE_FROM_FLYOUT,
}
export type CasesContextStoreAction =
| {
Expand All @@ -47,25 +50,32 @@ export type CasesContextStoreAction =
type: CasesContextStoreActionsList.OPEN_ADD_TO_CASE_MODAL;
payload: AllCasesSelectorModalProps;
}
| { type: CasesContextStoreActionsList.CLOSE_ADD_TO_CASE_MODAL };
| { type: CasesContextStoreActionsList.CLOSE_ADD_TO_CASE_MODAL }
| { type: CasesContextStoreActionsList.SUBMIT_CASE_FROM_FLYOUT };

export const casesContextReducer: React.Reducer<CasesContextState, CasesContextStoreAction> = (
state: CasesContextState,
action: CasesContextStoreAction
): CasesContextState => {
switch (action.type) {
case CasesContextStoreActionsList.OPEN_CREATE_CASE_FLYOUT: {
return { ...state, createCaseFlyout: { isFlyoutOpen: true, props: action.payload } };
return {
...state,
createCaseFlyout: { ...state.createCaseFlyout, isFlyoutOpen: true, props: action.payload },
Comment thread
stephmilovic marked this conversation as resolved.
Outdated
};
}
case CasesContextStoreActionsList.CLOSE_CREATE_CASE_FLYOUT: {
return { ...state, createCaseFlyout: { isFlyoutOpen: false } };
return { ...state, createCaseFlyout: { ...state.createCaseFlyout, isFlyoutOpen: false } };
}
case CasesContextStoreActionsList.OPEN_ADD_TO_CASE_MODAL: {
return { ...state, selectCaseModal: { isModalOpen: true, props: action.payload } };
}
case CasesContextStoreActionsList.CLOSE_ADD_TO_CASE_MODAL: {
return { ...state, selectCaseModal: { isModalOpen: false } };
}
case CasesContextStoreActionsList.SUBMIT_CASE_FROM_FLYOUT: {
return { ...state, createCaseFlyout: { ...state.createCaseFlyout, isSubmit: true } };
}
default:
assertNever(action);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('Cases context UI', () => {
...getInitialCasesContextState(),
createCaseFlyout: {
isFlyoutOpen: true,
isSubmit: false,
props: {
attachments: [],
},
Expand All @@ -48,6 +49,7 @@ describe('Cases context UI', () => {
...getInitialCasesContextState(),
createCaseFlyout: {
isFlyoutOpen: false,
isSubmit: false,
},
};
appMock.render(<CasesGlobalComponents state={state} />);
Expand Down
11 changes: 11 additions & 0 deletions x-pack/plugins/cases/public/components/cases_context/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface CasesContextValue {
features: CasesFeaturesAllRequired;
releasePhase: ReleasePhase;
dispatch: CasesContextValueDispatch;
isSubmit: boolean;
}

export interface CasesContextProps
Expand Down Expand Up @@ -90,6 +91,7 @@ export const CasesProvider: React.FC<{ value: CasesContextProps }> = ({
),
releasePhase,
dispatch,
isSubmit: false,
}));

/**
Expand All @@ -114,6 +116,15 @@ export const CasesProvider: React.FC<{ value: CasesContextProps }> = ({
}
}, [appTitle, appId]);

useEffect(() => {
if (state.createCaseFlyout.isSubmit) {
setValue((prev) => ({
...prev,
isSubmit: true,
}));
}
}, [state.createCaseFlyout.isSubmit]);

Comment thread
stephmilovic marked this conversation as resolved.
Outdated
return isCasesContextValue(value) ? (
<CasesContext.Provider value={value}>
<CasesGlobalComponents state={state} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface CreateCaseFlyoutProps {
onSuccess?: (theCase: Case) => Promise<void>;
attachments?: CaseAttachmentsWithoutOwner;
headerContent?: React.ReactNode;
initialValue?: Partial<Case>;
}

const StyledFlyout = styled(EuiFlyout)`
Expand Down Expand Up @@ -72,7 +73,7 @@ const FormWrapper = styled.div`
`;

export const CreateCaseFlyout = React.memo<CreateCaseFlyoutProps>(
({ afterCaseCreated, onClose, onSuccess, attachments, headerContent }) => {
({ afterCaseCreated, onClose, onSuccess, attachments, headerContent, initialValue }) => {
const handleCancel = onClose || function () {};
const handleOnSuccess = onSuccess || async function () {};

Expand All @@ -99,6 +100,7 @@ export const CreateCaseFlyout = React.memo<CreateCaseFlyoutProps>(
onCancel={handleCancel}
onSuccess={handleOnSuccess}
withSteps={false}
initialValue={initialValue}
/>
</FormWrapper>
</StyledEuiFlyoutBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('use cases add to new case flyout hook', () => {
externalReferenceAttachmentTypeRegistry,
persistableStateAttachmentTypeRegistry,
owner: ['test'],
isSubmit: false,
permissions: allCasesPermissions(),
appId: 'test',
appTitle: 'jest',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export const useCasesAddToNewCaseFlyout = (props: AddToNewCaseFlyoutProps = {})
const { dispatch } = useCasesContext();
const casesToasts = useCasesToast();

const submitFromFlyout = useCallback(() => {
dispatch({
type: CasesContextStoreActionsList.SUBMIT_CASE_FROM_FLYOUT,
});
}, [dispatch]);
Comment thread
stephmilovic marked this conversation as resolved.
Outdated

const closeFlyout = useCallback(() => {
dispatch({
type: CasesContextStoreActionsList.CLOSE_CREATE_CASE_FLYOUT,
Expand Down Expand Up @@ -73,6 +79,7 @@ export const useCasesAddToNewCaseFlyout = (props: AddToNewCaseFlyoutProps = {})
return {
open: openFlyout,
close: closeFlyout,
submit: submitFromFlyout,
};
};

Expand Down
15 changes: 12 additions & 3 deletions x-pack/plugins/cases/public/components/create/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import React, { useMemo } from 'react';
import React, { useEffect, useMemo } from 'react';
import {
EuiButtonEmpty,
EuiFlexGroup,
Expand Down Expand Up @@ -70,15 +70,22 @@ export interface CreateCaseFormProps extends Pick<Partial<CreateCaseFormFieldsPr
) => Promise<void>;
timelineIntegration?: CasesTimelineIntegration;
attachments?: CaseAttachmentsWithoutOwner;
initialValue?: Partial<Case>;
}

const empty: ActionConnector[] = [];
export const CreateCaseFormFields: React.FC<CreateCaseFormFieldsProps> = React.memo(
({ connectors, isLoadingConnectors, withSteps }) => {
const { isSubmitting } = useFormContext();
const { isSubmitting, submit } = useFormContext();
const { isSyncAlertsEnabled, caseAssignmentAuthorized } = useCasesFeatures();

const { owner } = useCasesContext();
const { owner, isSubmit } = useCasesContext();

useEffect(() => {
console.log('useEffect', isSubmit);
if (isSubmit) submit();
}, [isSubmit, submit]);

const availableOwners = useAvailableCasesOwners();
const canShowCaseSolutionSelection = !owner.length && availableOwners.length;

Expand Down Expand Up @@ -181,12 +188,14 @@ export const CreateCaseForm: React.FC<CreateCaseFormProps> = React.memo(
onSuccess,
timelineIntegration,
attachments,
initialValue,
}) => (
<CasesTimelineIntegrationProvider timelineIntegration={timelineIntegration}>
<FormContext
afterCaseCreated={afterCaseCreated}
onSuccess={onSuccess}
attachments={attachments}
initialValue={initialValue}
>
<CreateCaseFormFields
connectors={empty}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ interface Props {
children?: JSX.Element | JSX.Element[];
onSuccess?: (theCase: Case) => Promise<void>;
attachments?: CaseAttachmentsWithoutOwner;
initialValue?: Partial<Case>;
Comment thread
stephmilovic marked this conversation as resolved.
Outdated
}

export const FormContext: React.FC<Props> = ({
afterCaseCreated,
children,
onSuccess,
attachments,
initialValue,
}) => {
const { data: connectors = [], isLoading: isLoadingConnectors } = useGetConnectors();
const { owner, appId } = useCasesContext();
Expand Down Expand Up @@ -128,7 +130,7 @@ export const FormContext: React.FC<Props> = ({
);

const { form } = useForm<FormProps>({
defaultValue: initialCaseValue,
defaultValue: { ...initialCaseValue, ...initialValue },
options: { stripEmptyFields: false },
schema,
onSubmit: submitCase,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,10 @@ It was important that the `EuiTourStep` **anchor** is in the DOM when the tour s
anchor: `[data-test-subj="create-case-flyout"]`,
anchorPosition: 'leftUp',
dataTestSubj: getTourAnchor(5, SecurityStepId.alertsCases),
hideNextButton: true,
}
```

Notice that the **anchor prop is defined** as `[data-test-subj="create-case-flyout"]` in the step 5 config. There is also a `hideNextButton` boolean utilized here.
Notice that the **anchor prop is defined** as `[data-test-subj="create-case-flyout"]` in the step 5 config.
As you can see pictured below, the tour step anchor is the create case flyout and the next button is hidden.

<img width="1336" alt="5" src="https://user-images.githubusercontent.com/6935300/197848670-09a6fa58-7417-4c9b-9be0-fb58224c2dc8.png">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ export const enum AlertsCasesTourSteps {

export type StepConfig = Pick<
EuiTourStepProps,
'step' | 'content' | 'anchorPosition' | 'title' | 'initialFocus' | 'anchor'
'step' | 'content' | 'anchorPosition' | 'title' | 'initialFocus' | 'anchor' | 'offset'
> & {
anchor?: ElementTarget;
dataTestSubj: string;
hideNextButton?: boolean;
imageConfig?: {
altText: string;
src: string;
Expand Down Expand Up @@ -79,7 +78,6 @@ const alertsCasesConfig: StepConfig[] = [
),
anchorPosition: 'rightUp',
dataTestSubj: getTourAnchor(AlertsCasesTourSteps.expandEvent, SecurityStepId.alertsCases),
hideNextButton: true,
},
{
...defaultConfig,
Expand Down Expand Up @@ -119,7 +117,6 @@ const alertsCasesConfig: StepConfig[] = [
}),
anchorPosition: 'upRight',
dataTestSubj: getTourAnchor(AlertsCasesTourSteps.addAlertToCase, SecurityStepId.alertsCases),
hideNextButton: true,
},
{
...defaultConfig,
Expand All @@ -133,13 +130,25 @@ const alertsCasesConfig: StepConfig[] = [
defaultMessage: `In addition to the alert, you can add any relevant information you need to the case.`,
}
),
anchor: `[data-test-subj="create-case-flyout"]`,
anchor: `[data-test-subj="create-case-flyout"] [data-test-subj="caseTitle"] label`,
anchorPosition: 'leftUp',
dataTestSubj: getTourAnchor(AlertsCasesTourSteps.createCase, SecurityStepId.alertsCases),
hideNextButton: true,
offset: 20,
},
];

export const sampleCase = {
title: i18n.translate('xpack.securitySolution.guided_onboarding.tour.createCase.title', {
defaultMessage: `Demo signal detected`,
}),
description: i18n.translate(
'xpack.securitySolution.guided_onboarding.tour.createCase.description',
{
defaultMessage: `This is where you'd document a malicious signal. You can include whatever information is relevant to the case and would be helpful for anyone else that needs to read up on it.`,
}
),
};

interface SecurityTourConfig {
[SecurityStepId.rules]: StepConfig[];
[SecurityStepId.alertsCases]: StepConfig[];
Expand Down
Loading