Skip to content

Commit

Permalink
More fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
clintandrewhall committed Oct 13, 2021
1 parent 6d6e501 commit dbaa8ab
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 1,915 deletions.
1,861 changes: 20 additions & 1,841 deletions src/plugins/custom_integrations/public/services/stub/fixtures/integrations.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const searchIdField = 'id';
export const fieldsToSearch = ['name', 'title', 'description'];

export function useLocalSearch(packageList: IntegrationCardItem[]) {
const localSearchRef = useRef<LocalSearch | null>(null);
const localSearchRef = useRef<LocalSearch>(new LocalSearch(searchIdField));

useEffect(() => {
const localSearch = new LocalSearch(searchIdField);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ export default {
} as Meta;

export const IntegrationPreference = () => {
return <Component onChange={action('onChange')} />;
return <Component initialType="recommended" onChange={action('onChange')} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@
*/

import React from 'react';
import styled from 'styled-components';

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiPanel, EuiLink, EuiText, EuiForm, EuiRadioGroup, EuiSpacer } from '@elastic/eui';
import {
EuiPanel,
EuiLink,
EuiText,
EuiForm,
EuiRadioGroup,
EuiSpacer,
EuiIconTip,
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';

import { SHIPPER_DISPLAY } from '../../../../../../../../../src/plugins/custom_integrations/common';

export type IntegrationPreferenceType = 'beats' | 'agent';
export type IntegrationPreferenceType = 'recommended' | 'beats' | 'agent';

interface Option {
type: IntegrationPreferenceType;
label: string;
label: React.ReactNode;
}

export interface Props {
Expand All @@ -37,30 +46,58 @@ const link = (
const title = (
<FormattedMessage
id="xpack.fleet.epm.integrationPreference.title"
defaultMessage="When an integration is available for {link}, use:"
defaultMessage="When an integration is available for {link}, show:"
values={{ link }}
/>
);

export const IntegrationPreference = ({ initialType, onChange }: Props) => {
const [idSelected, setIdSelected] = React.useState<IntegrationPreferenceType>(initialType);
const recommendedTooltip = (
<FormattedMessage
id="xpack.fleet.epm.integrationPreference.recommendedTooltip"
defaultMessage="Generally available (GA) integrations are recommended over beta and experimental."
/>
);

const Item = styled(EuiFlexItem)`
padding-left: ${(props) => props.theme.eui.euiSizeXS};
`;

const options: Option[] = [
{
type: 'agent',
label: i18n.translate('xpack.fleet.epm.integrationPreference.elasticAgentLabel', {
defaultMessage: 'Elastic Agent (recommended)',
}),
},
{
type: 'beats',
label: SHIPPER_DISPLAY.beats,
},
];
const options: Option[] = [
{
type: 'recommended',
label: (
<EuiFlexGroup alignItems="center" gutterSize="none">
<EuiFlexItem grow={false}>
{i18n.translate('xpack.fleet.epm.integrationPreference.recommendedLabel', {
defaultMessage: 'Recommended',
})}
</EuiFlexItem>
<Item>
<EuiIconTip content={recommendedTooltip} />
</Item>
</EuiFlexGroup>
),
},
{
type: 'agent',
label: i18n.translate('xpack.fleet.epm.integrationPreference.elasticAgentLabel', {
defaultMessage: 'Elastic Agent only',
}),
},
{
type: 'beats',
label: i18n.translate('xpack.fleet.epm.integrationPreference.beatsLabel', {
defaultMessage: 'Beats only',
}),
},
];

export const IntegrationPreference = ({ initialType, onChange }: Props) => {
const [idSelected, setIdSelected] = React.useState<IntegrationPreferenceType>(initialType);
const radios = options.map((option) => ({
id: option.type,
...option,
value: option.type,
label: option.label,
}));

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
* 2.0.
*/

import React, { memo, useMemo } from 'react';
import React, { memo, useMemo, useState } from 'react';
import { useLocation, useHistory, useParams } from 'react-router-dom';
import { i18n } from '@kbn/i18n';
import _ from 'lodash';
import { EuiHorizontalRule } from '@elastic/eui';

import { pagePathGetters } from '../../../../constants';
import {
Expand All @@ -31,6 +32,9 @@ import type { IntegrationCardItem } from '../../../../../../../common/types/mode

import { useMergeEprPackagesWithReplacements } from '../../../../hooks/use_merge_epr_with_replacements';

import type { IntegrationPreferenceType } from '../../components/integration_preference';
import { IntegrationPreference } from '../../components/integration_preference';

import { mergeCategoriesAndCount } from './util';
import { ALL_CATEGORY, CategoryFacets } from './category_facets';
import type { CategoryFacet } from './category_facets';
Expand Down Expand Up @@ -96,11 +100,14 @@ const title = i18n.translate('xpack.fleet.epmList.allTitle', {
// TODO: clintandrewhall - this component is hard to test due to the hooks, particularly those that use `http`
// or `location` to load data. Ideally, we'll split this into "connected" and "pure" components.
export const AvailablePackages: React.FC = memo(() => {
const [preference, setPreference] = useState<IntegrationPreferenceType>('recommended');
useBreadcrumbs('integrations_all');

const { selectedCategory, searchParam } = getParams(
useParams<CategoryParams>(),
useLocation().search
);

const history = useHistory();
const { getHref, getAbsolutePath } = useLink();

Expand All @@ -111,6 +118,7 @@ export const AvailablePackages: React.FC = memo(() => {
})[1];
history.push(url);
}

function setSearchTerm(search: string) {
// Use .replace so the browser's back button is not tied to single keystroke
history.replace(
Expand All @@ -121,32 +129,40 @@ export const AvailablePackages: React.FC = memo(() => {
const { data: eprPackages, isLoading: isLoadingAllPackages } = useGetPackages({
category: '',
});

const eprIntegrationList = useMemo(
() => packageListToIntegrationsList(eprPackages?.response || []),
[eprPackages]
);

const { value: replacementCustomIntegrations } = useGetReplacementCustomIntegrations();

const mergedEprPackages: Array<PackageListItem | CustomIntegration> =
useMergeEprPackagesWithReplacements(
eprIntegrationList || [],
replacementCustomIntegrations || []
preference === 'beats' ? [] : eprIntegrationList,
preference === 'agent' ? [] : replacementCustomIntegrations || []
);

const { loading: isLoadingAppendCustomIntegrations, value: appendCustomIntegrations } =
useGetAppendCustomIntegrations();

const eprAndCustomPackages: Array<CustomIntegration | PackageListItem> = [
...mergedEprPackages,
...(appendCustomIntegrations || []),
];

const cards: IntegrationCardItem[] = eprAndCustomPackages.map((item) => {
return mapToCard(getAbsolutePath, getHref, item);
});

cards.sort((a, b) => {
return a.title.localeCompare(b.title);
});

const { data: eprCategories, isLoading: isLoadingCategories } = useGetCategories({
include_policy_templates: true,
});

const categories = useMemo(() => {
const eprAndCustomCategories: CategoryFacet[] =
isLoadingCategories || !eprCategories
Expand All @@ -169,16 +185,24 @@ export const AvailablePackages: React.FC = memo(() => {
return null;
}

const controls = categories ? (
<CategoryFacets
isLoading={isLoadingCategories || isLoadingAllPackages || isLoadingAppendCustomIntegrations}
categories={categories}
selectedCategory={selectedCategory}
onCategoryChange={({ id }: CategoryFacet) => {
setSelectedCategory(id);
}}
/>
) : null;
let controls = [
<EuiHorizontalRule />,
<IntegrationPreference initialType={preference} onChange={setPreference} />,
];

if (categories) {
controls = [
<CategoryFacets
isLoading={isLoadingCategories || isLoadingAllPackages || isLoadingAppendCustomIntegrations}
categories={categories}
selectedCategory={selectedCategory}
onCategoryChange={({ id }) => {
setSelectedCategory(id);
}}
/>,
...controls,
];
}

const filteredCards = cards.filter((c) => {
if (selectedCategory === '') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,6 @@ export interface Props {
onCategoryChange: (category: CategoryFacet) => unknown;
}

export interface Props {
showCounts: boolean;
isLoading?: boolean;
categories: CategoryFacet[];
selectedCategory: string;
onCategoryChange: (category: CategoryFacet) => void;
}

export function CategoryFacets({
isLoading,
categories,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ import type { DynamicPage, DynamicPagePathValues, StaticPage } from '../../../..
import { INTEGRATIONS_ROUTING_PATHS, INTEGRATIONS_SEARCH_QUERYPARAM } from '../../../../constants';
import { DefaultLayout } from '../../../../layouts';

import type {
CustomIntegration,
IntegrationCategory,
} from '../../../../../../../../../../src/plugins/custom_integrations/common';
import type { IntegrationCategory } from '../../../../../../../../../../src/plugins/custom_integrations/common';
import type { CustomIntegration } from '../../../../../../../../../../src/plugins/custom_integrations/common';

import type { PackageListItem } from '../../../../types';

Expand All @@ -34,7 +32,10 @@ export const getParams = (params: CategoryParams, search: string) => {
const selectedCategory = category || '';
const queryParams = new URLSearchParams(search);
const searchParam = queryParams.get(INTEGRATIONS_SEARCH_QUERYPARAM) || '';
return { selectedCategory, searchParam };
return { selectedCategory, searchParam } as {
selectedCategory: IntegrationCategory & '';
searchParam: string;
};
};

export const categoryExists = (category: string, categories: CategoryFacet[]) => {
Expand Down
27 changes: 23 additions & 4 deletions x-pack/plugins/fleet/storybook/context/fixtures/packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const response: GetPackagesResponse['response'] = [
path: '/package/ga/not_installed',
id: 'ga_not_installed',
status: 'not_installed',
categories: ['aws', 'azure'],
},
{
name: 'ga_beats',
Expand All @@ -31,6 +32,7 @@ export const response: GetPackagesResponse['response'] = [
path: '/package/ga/not_installed/beats',
id: 'ga_not_installed_beat',
status: 'not_installed',
categories: ['azure', 'cloud', 'config_management'],
},
{
name: 'ga_installed',
Expand Down Expand Up @@ -66,6 +68,7 @@ export const response: GetPackagesResponse['response'] = [
updated_at: '2021-08-25T19:44:53.517Z',
version: 'WzczMTIsNF0=',
},
categories: ['cloud', 'containers'],
},
{
name: 'ga_installed_update',
Expand Down Expand Up @@ -101,6 +104,7 @@ export const response: GetPackagesResponse['response'] = [
updated_at: '2021-08-25T19:44:53.517Z',
version: 'WzczMTIsNF0=',
},
categories: ['cloud', 'crm', 'custom'],
},
{
name: 'beta_not_installed',
Expand All @@ -125,6 +129,7 @@ export const response: GetPackagesResponse['response'] = [
path: '/package/beta/not_installed/beats',
id: 'beta_beats',
status: 'not_installed',
categories: ['datastore', 'elastic_stack', 'google_cloud'],
},
{
name: 'beta_installed',
Expand Down Expand Up @@ -160,6 +165,7 @@ export const response: GetPackagesResponse['response'] = [
updated_at: '2021-08-25T19:44:53.517Z',
version: 'WzczMTIsNF0=',
},
categories: ['elastic_stack', 'languages'],
},
{
name: 'beta_installed_update',
Expand Down Expand Up @@ -195,6 +201,7 @@ export const response: GetPackagesResponse['response'] = [
updated_at: '2021-08-25T19:44:53.517Z',
version: 'WzczMTIsNF0=',
},
categories: ['message_queue', 'monitoring'],
},
{
name: 'exp_not_installed',
Expand All @@ -207,18 +214,28 @@ export const response: GetPackagesResponse['response'] = [
path: '/package/exp/not_installed',
id: 'exp_not_installed',
status: 'not_installed',
categories: ['monitoring', 'network', 'notification'],
},
{
name: 'exp_not_installed',
name: 'exp_beats',
title: 'j. Experimental, has Beats',
version: '0.0.9',
release: 'experimental',
description: 'A package that is Experimental and not installed',
type: 'integration',
download: '/epr/exp/not_installed',
path: '/package/exp/not_installed',
id: 'exp_not_installed',
download: '/epr/exp/not_installed/beats',
path: '/package/exp/not_installed/beats',
id: 'exp_beats',
status: 'not_installed',
policy_templates: [
{
name: '',
description: '',
title: '',
categories: ['datastore'],
},
],
categories: ['version_control', 'web'],
},
{
name: 'exp_installed',
Expand Down Expand Up @@ -254,6 +271,7 @@ export const response: GetPackagesResponse['response'] = [
updated_at: '2021-08-25T19:44:53.517Z',
version: 'WzczMTIsNF0=',
},
categories: ['os_system', 'productivity'],
},
{
name: 'exp_installed_update',
Expand Down Expand Up @@ -289,5 +307,6 @@ export const response: GetPackagesResponse['response'] = [
updated_at: '2021-08-25T19:44:53.517Z',
version: 'WzczMTIsNF0=',
},
categories: ['aws', 'cloud', 'elastic_stack'],
},
];
Loading

0 comments on commit dbaa8ab

Please sign in to comment.