-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into fix-osquery-no-response-actions
- Loading branch information
Showing
39 changed files
with
1,253 additions
and
37 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
packages/kbn-management/settings/components/form/README.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
id: management/settings/components/form | ||
slug: /management/settings/components/form | ||
title: Management Settings Form Component | ||
description: A package containing a component for rendering the form in the Advanced Settings UI. | ||
tags: ['management', 'settings'] | ||
date: 2023-09-12 | ||
--- | ||
|
||
## Description | ||
|
||
This package contains a component for rendering the Advanced Settings UI form that contains `FieldRow` components, each of which displays a single UiSetting field row. | ||
The form also handles the logic for saving any changes to the UiSettings values by directly communicating with the uiSettings service. | ||
|
||
|
||
## Notes | ||
|
||
- This implementation was extracted from the `Form` component in the `advancedSettings` plugin. |
79 changes: 79 additions & 0 deletions
79
packages/kbn-management/settings/components/form/bottom_bar/bottom_bar.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* 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 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 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import React from 'react'; | ||
import { fireEvent, render } from '@testing-library/react'; | ||
import { | ||
BottomBar, | ||
BottomBarProps, | ||
DATA_TEST_SUBJ_SAVE_BUTTON, | ||
DATA_TEST_SUBJ_CANCEL_BUTTON, | ||
} from './bottom_bar'; | ||
import { wrap } from '../mocks'; | ||
|
||
const saveAll = jest.fn(); | ||
const clearAllUnsaved = jest.fn(); | ||
const unsavedChangesCount = 3; | ||
|
||
const defaultProps: BottomBarProps = { | ||
onSaveAll: saveAll, | ||
onClearAllUnsaved: clearAllUnsaved, | ||
hasInvalidChanges: false, | ||
unsavedChangesCount, | ||
isLoading: false, | ||
}; | ||
|
||
const unsavedChangesCountText = unsavedChangesCount + ' unsaved settings'; | ||
|
||
describe('BottomBar', () => { | ||
it('renders without errors', () => { | ||
const { container } = render(wrap(<BottomBar {...defaultProps} />)); | ||
expect(container).toBeInTheDocument(); | ||
}); | ||
|
||
it('fires saveAll when the Save button is clicked', () => { | ||
const { getByTestId } = render(wrap(<BottomBar {...defaultProps} />)); | ||
|
||
const input = getByTestId(DATA_TEST_SUBJ_SAVE_BUTTON); | ||
fireEvent.click(input); | ||
expect(saveAll).toHaveBeenCalled(); | ||
}); | ||
|
||
it('fires clearAllUnsaved when the Cancel button is clicked', () => { | ||
const { getByTestId } = render(wrap(<BottomBar {...defaultProps} />)); | ||
|
||
const input = getByTestId(DATA_TEST_SUBJ_CANCEL_BUTTON); | ||
fireEvent.click(input); | ||
expect(saveAll).toHaveBeenCalled(); | ||
}); | ||
|
||
it('renders unsaved changes count', () => { | ||
const { getByText } = render(wrap(<BottomBar {...defaultProps} />)); | ||
|
||
expect(getByText(unsavedChangesCountText)).toBeInTheDocument(); | ||
}); | ||
|
||
it('save button is disabled when there are invalid changes', () => { | ||
const { getByTestId } = render( | ||
wrap(<BottomBar {...{ ...defaultProps, hasInvalidChanges: true }} />) | ||
); | ||
|
||
const input = getByTestId(DATA_TEST_SUBJ_SAVE_BUTTON); | ||
expect(input).toBeDisabled(); | ||
}); | ||
|
||
it('save button is loading when in loading state', () => { | ||
const { getByTestId, getByLabelText } = render( | ||
wrap(<BottomBar {...{ ...defaultProps, isLoading: true }} />) | ||
); | ||
|
||
const input = getByTestId(DATA_TEST_SUBJ_SAVE_BUTTON); | ||
expect(input).toBeDisabled(); | ||
expect(getByLabelText('Loading')).toBeInTheDocument(); | ||
}); | ||
}); |
104 changes: 104 additions & 0 deletions
104
packages/kbn-management/settings/components/form/bottom_bar/bottom_bar.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* 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 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 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import React from 'react'; | ||
|
||
import { | ||
EuiBottomBar, | ||
EuiButton, | ||
EuiButtonEmpty, | ||
EuiFlexGroup, | ||
EuiFlexItem, | ||
EuiToolTip, | ||
} from '@elastic/eui'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { UnsavedCount } from './unsaved_count'; | ||
import { useFormStyles } from '../form.styles'; | ||
|
||
export const DATA_TEST_SUBJ_SAVE_BUTTON = 'settings-save-button'; | ||
export const DATA_TEST_SUBJ_CANCEL_BUTTON = 'settings-cancel-button'; | ||
|
||
/** | ||
* Props for a {@link BottomBar} component. | ||
*/ | ||
export interface BottomBarProps { | ||
onSaveAll: () => void; | ||
onClearAllUnsaved: () => void; | ||
hasInvalidChanges: boolean; | ||
isLoading: boolean; | ||
unsavedChangesCount: number; | ||
} | ||
|
||
/** | ||
* Component for displaying the bottom bar of a {@link Form}. | ||
*/ | ||
export const BottomBar = ({ | ||
onSaveAll, | ||
onClearAllUnsaved, | ||
hasInvalidChanges, | ||
isLoading, | ||
unsavedChangesCount, | ||
}: BottomBarProps) => { | ||
const { cssFormButton, cssFormUnsavedCount } = useFormStyles(); | ||
|
||
return ( | ||
<EuiBottomBar> | ||
<EuiFlexGroup | ||
justifyContent="spaceBetween" | ||
alignItems="center" | ||
responsive={false} | ||
gutterSize="s" | ||
> | ||
<EuiFlexItem grow={false} css={cssFormUnsavedCount}> | ||
<UnsavedCount unsavedCount={unsavedChangesCount} /> | ||
</EuiFlexItem> | ||
<EuiFlexItem /> | ||
<EuiFlexItem grow={false}> | ||
<EuiButtonEmpty | ||
css={cssFormButton} | ||
color="ghost" | ||
size="s" | ||
iconType="cross" | ||
onClick={onClearAllUnsaved} | ||
data-test-subj={DATA_TEST_SUBJ_CANCEL_BUTTON} | ||
> | ||
{i18n.translate('management.settings.form.cancelButtonLabel', { | ||
defaultMessage: 'Cancel changes', | ||
})} | ||
</EuiButtonEmpty> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<EuiToolTip | ||
content={ | ||
hasInvalidChanges && | ||
i18n.translate('management.settings.form.saveButtonTooltipWithInvalidChanges', { | ||
defaultMessage: 'Fix invalid settings before saving.', | ||
}) | ||
} | ||
> | ||
<EuiButton | ||
css={cssFormButton} | ||
disabled={hasInvalidChanges} | ||
color="success" | ||
fill | ||
size="s" | ||
iconType="check" | ||
onClick={onSaveAll} | ||
isLoading={isLoading} | ||
data-test-subj={DATA_TEST_SUBJ_SAVE_BUTTON} | ||
> | ||
{i18n.translate('management.settings.form.saveButtonLabel', { | ||
defaultMessage: 'Save changes', | ||
})} | ||
</EuiButton> | ||
</EuiToolTip> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiBottomBar> | ||
); | ||
}; |
9 changes: 9 additions & 0 deletions
9
packages/kbn-management/settings/components/form/bottom_bar/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* | ||
* 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 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 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
export { BottomBar } from './bottom_bar'; |
41 changes: 41 additions & 0 deletions
41
packages/kbn-management/settings/components/form/bottom_bar/unsaved_count.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* 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 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 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import React from 'react'; | ||
|
||
import { EuiText } from '@elastic/eui'; | ||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
import { useFormStyles } from '../form.styles'; | ||
|
||
/** | ||
* Props for a {@link UnsavedCount} component. | ||
*/ | ||
interface UnsavedCountProps { | ||
unsavedCount: number; | ||
} | ||
|
||
/** | ||
* Component for displaying the count of unsaved changes in a {@link BottomBar}. | ||
*/ | ||
export const UnsavedCount = ({ unsavedCount }: UnsavedCountProps) => { | ||
const { cssFormUnsavedCountMessage } = useFormStyles(); | ||
return ( | ||
<EuiText size="s" color="ghost" css={cssFormUnsavedCountMessage}> | ||
<FormattedMessage | ||
id="management.settings.form.countOfSettingsChanged" | ||
defaultMessage="{unsavedCount} unsaved {unsavedCount, plural, | ||
one {setting} | ||
other {settings} | ||
}" | ||
values={{ | ||
unsavedCount, | ||
}} | ||
/> | ||
</EuiText> | ||
); | ||
}; |
33 changes: 33 additions & 0 deletions
33
packages/kbn-management/settings/components/form/form.styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 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 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { useEuiTheme, euiBreakpoint } from '@elastic/eui'; | ||
import { css } from '@emotion/react'; | ||
|
||
/** | ||
* A React hook that provides stateful `css` classes for the {@link Form} component. | ||
*/ | ||
export const useFormStyles = () => { | ||
const euiTheme = useEuiTheme(); | ||
const { size, colors } = euiTheme.euiTheme; | ||
|
||
return { | ||
cssFormButton: css` | ||
width: 100%; | ||
`, | ||
cssFormUnsavedCount: css` | ||
${euiBreakpoint(euiTheme, ['xs'])} { | ||
display: none; | ||
} | ||
`, | ||
cssFormUnsavedCountMessage: css` | ||
box-shadow: -${size.xs} 0 ${colors.warning}; | ||
padding-left: ${size.s}; | ||
`, | ||
}; | ||
}; |
Oops, something went wrong.