Skip to content

Commit

Permalink
[Security Solution] Add VersionPicker component (elastic#188302)
Browse files Browse the repository at this point in the history
**Partially addresses: elastic#171520

## Summary

This PR adds the `VersionPicker` component ThreeWayDiff UI. This
component is a part of the `ComparisonSide` component ([see it on the
Miro
diagram](https://miro.com/app/board/uXjVK0gqjjQ=/?moveToWidget=3458764594147853908&cot=14)).
`ComparisonSide` will display the read-only diff between two selected
field versions.

These component is not yet connected to the Upgrade flyout. You can view
and test it in Storybook by running `yarn storybook security_solution`
in the root Kibana dir. Go to `http://localhost:9001` once the Storybook
is up and running.

<img width="939" alt="Scherm­afbeelding 2024-07-19 om 11 21 55"
src="https://github.com/user-attachments/assets/f0c5de6c-a1dc-4efc-9466-53033b45a300">
  • Loading branch information
nikitaindik authored Jul 20, 2024
1 parent 0dc3fd1 commit 77afb68
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 type { EuiSelectOption } from '@elastic/eui';
import * as i18n from './translations';

export enum SelectedVersions {
BaseTarget = 'base_target',
BaseCurrent = 'base_current',
BaseFinal = 'base_final',
CurrentTarget = 'current_target',
CurrentFinal = 'current_final',
TargetFinal = 'target_final',
}

export const CURRENT_OPTIONS: EuiSelectOption[] = [
{
value: SelectedVersions.CurrentFinal,
text: i18n.CURRENT_VS_FINAL,
},
{
value: SelectedVersions.CurrentTarget,
text: i18n.CURRENT_VS_TARGET,
},
];

export const TARGET_OPTIONS: EuiSelectOption[] = [
{
value: SelectedVersions.TargetFinal,
text: i18n.TARGET_VS_FINAL,
},
];

export const BASE_OPTIONS: EuiSelectOption[] = [
{
value: SelectedVersions.BaseFinal,
text: i18n.BASE_VS_FINAL,
},
{
value: SelectedVersions.BaseTarget,
text: i18n.BASE_VS_TARGET,
},
{
value: SelectedVersions.BaseCurrent,
text: i18n.BASE_VS_CURRENT,
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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 { i18n } from '@kbn/i18n';

export const BASE_VS_TARGET = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsTargetLabel',
{
defaultMessage: 'Base vs Target',
}
);

export const BASE_VS_CURRENT = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsCurrentLabel',
{
defaultMessage: 'Base vs Current',
}
);

export const BASE_VS_FINAL = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.baseVsFinalLabel',
{
defaultMessage: 'Base vs Final',
}
);

export const CURRENT_VS_TARGET = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsTargetLabel',
{
defaultMessage: 'Current vs Target',
}
);

export const CURRENT_VS_FINAL = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.currentVsFinalLabel',
{
defaultMessage: 'Current vs Final',
}
);

export const TARGET_VS_FINAL = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.targetVsFinalLabel',
{
defaultMessage: 'Target vs Final',
}
);

export const VERSION_PICKER_ARIA_LABEL = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.upgradeRules.versionsPicker.ariaLabel',
{
defaultMessage: 'Select versions to compare',
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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, { useState } from 'react';
import type { Story } from '@storybook/react';
import { VersionsPicker } from './versions_picker';
import { SelectedVersions } from './constants';

export default {
component: VersionsPicker,
title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/VersionsPicker',
argTypes: {
hasBaseVersion: {
control: 'boolean',
description: 'Indicates whether the base version of a field is available',
defaultValue: true,
},
},
};

const Template: Story<{ hasBaseVersion: boolean }> = (args) => {
const [selectedVersions, setSelectedVersions] = useState<SelectedVersions>(
SelectedVersions.CurrentFinal
);

return (
<VersionsPicker
hasBaseVersion={args.hasBaseVersion}
selectedVersions={selectedVersions}
onChange={setSelectedVersions}
/>
);
};

export const Default = Template.bind({});
Default.args = {
hasBaseVersion: true,
};

export const NoBaseVersion = Template.bind({});
NoBaseVersion.args = {
hasBaseVersion: false,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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, { useCallback, useMemo } from 'react';
import { EuiSelect } from '@elastic/eui';
import type { EuiSelectOption } from '@elastic/eui';
import { BASE_OPTIONS, CURRENT_OPTIONS, TARGET_OPTIONS, SelectedVersions } from './constants';
import * as i18n from './translations';

interface VersionsPickerProps {
hasBaseVersion: boolean;
selectedVersions: SelectedVersions;
onChange: (pickedVersions: SelectedVersions) => void;
}

export function VersionsPicker({
hasBaseVersion,
selectedVersions = SelectedVersions.CurrentFinal,
onChange,
}: VersionsPickerProps) {
const options: EuiSelectOption[] = useMemo(
() => [...CURRENT_OPTIONS, ...TARGET_OPTIONS, ...(hasBaseVersion ? BASE_OPTIONS : [])],
[hasBaseVersion]
);

const handleChange = useCallback(
(changeEvent) => {
onChange(changeEvent.target.value as SelectedVersions);
},
[onChange]
);

return (
<EuiSelect
options={options}
value={selectedVersions}
onChange={handleChange}
aria-label={i18n.VERSION_PICKER_ARIA_LABEL}
/>
);
}

0 comments on commit 77afb68

Please sign in to comment.