Skip to content

Commit

Permalink
[Fleet] Display category badge besides integrations list searchbar (#…
Browse files Browse the repository at this point in the history
…140391)

* [Fleet] Display category badge besides integrations list  searchbar

* Fix padding in button

* Avoid clearing query when clearing category

* Fix cypress test

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
criamico and kibanamachine authored Sep 13, 2022
1 parent dfafa26 commit 2be75d5
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 63 deletions.
81 changes: 55 additions & 26 deletions x-pack/plugins/fleet/cypress/integration/integrations_real.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,49 @@ import {
POLICIES_TAB,
SETTINGS_TAB,
UPDATE_PACKAGE_BTN,
INTEGRATIONS_SEARCHBAR_INPUT,
INTEGRATIONS_SEARCHBAR,
SETTINGS,
INTEGRATION_POLICIES_UPGRADE_CHECKBOX,
INTEGRATION_LIST,
getIntegrationCategories,
} from '../screens/integrations';
import { LOADING_SPINNER, CONFIRM_MODAL } from '../screens/navigation';
import { ADD_PACKAGE_POLICY_BTN } from '../screens/fleet';
import { cleanupAgentPolicies } from '../tasks/cleanup';

function setupIntegrations() {
cy.intercept(
'/api/fleet/epm/packages?*',
{
middleware: true,
},
(req) => {
req.on('before:response', (res) => {
// force all API responses to not be cached
res.headers['cache-control'] = 'no-store';
});
}
).as('packages');

navigateTo(INTEGRATIONS);
cy.wait('@packages');
}

it('should install integration without policy', () => {
cy.visit('/app/integrations/detail/tomcat/settings');

cy.getBySel(SETTINGS.INSTALL_ASSETS_BTN).click();
cy.get('.euiCallOut').contains('This action will install 1 assets');
cy.getBySel(CONFIRM_MODAL.CONFIRM_BUTTON).click();

cy.getBySel(LOADING_SPINNER).should('not.exist');

cy.getBySel(SETTINGS.UNINSTALL_ASSETS_BTN).click();
cy.getBySel(CONFIRM_MODAL.CONFIRM_BUTTON).click();
cy.getBySel(LOADING_SPINNER).should('not.exist');
cy.getBySel(SETTINGS.INSTALL_ASSETS_BTN).should('exist');
});

describe('Add Integration - Real API', () => {
const integration = 'apache';

Expand All @@ -41,29 +76,6 @@ describe('Add Integration - Real API', () => {
cleanupAgentPolicies();
});

function addAndVerifyIntegration() {
cy.intercept(
'/api/fleet/epm/packages?*',
{
middleware: true,
},
(req) => {
req.on('before:response', (res) => {
// force all API responses to not be cached
res.headers['cache-control'] = 'no-store';
});
}
).as('packages');

navigateTo(INTEGRATIONS);
cy.wait('@packages');
cy.getBySel(LOADING_SPINNER).should('not.exist');
cy.getBySel(INTEGRATIONS_SEARCHBAR_INPUT).type('Apache');
cy.getBySel(getIntegrationCard(integration)).click();
addIntegration();
cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1');
}

it('should install integration without policy', () => {
cy.visit('/app/integrations/detail/tomcat/settings');

Expand All @@ -80,7 +92,12 @@ describe('Add Integration - Real API', () => {
});

it('should display Apache integration in the Policies list once installed ', () => {
addAndVerifyIntegration();
setupIntegrations();
cy.getBySel(LOADING_SPINNER).should('not.exist');
cy.getBySel(INTEGRATIONS_SEARCHBAR.INPUT).clear().type('Apache');
cy.getBySel(getIntegrationCard(integration)).click();
addIntegration();
cy.getBySel(INTEGRATION_NAME_LINK).contains('apache-1');
cy.getBySel(AGENT_POLICY_NAME_LINK).contains('Agent policy 1');
});

Expand Down Expand Up @@ -118,7 +135,7 @@ describe('Add Integration - Real API', () => {
cy.getBySel(ADD_PACKAGE_POLICY_BTN).click();
cy.wait('@packages');
cy.getBySel(LOADING_SPINNER).should('not.exist');
cy.getBySel(INTEGRATIONS_SEARCHBAR_INPUT).type('Apache');
cy.getBySel(INTEGRATIONS_SEARCHBAR.INPUT).clear().type('Apache');
cy.getBySel(getIntegrationCard(integration)).click();
addIntegration({ useExistingPolicy: true });
cy.get('.euiBasicTable-loading').should('not.exist');
Expand Down Expand Up @@ -152,4 +169,16 @@ describe('Add Integration - Real API', () => {
cy.getBySel(PACKAGE_VERSION).contains(newVersion);
});
});

it('should filter integrations by category', () => {
setupIntegrations();
cy.getBySel(getIntegrationCategories('aws')).click();
cy.getBySel(INTEGRATIONS_SEARCHBAR.BADGE).contains('AWS').should('exist');
cy.getBySel(INTEGRATION_LIST).find('.euiCard').should('have.length', 30);

cy.getBySel(INTEGRATIONS_SEARCHBAR.INPUT).clear().type('Cloud');
cy.getBySel(INTEGRATION_LIST).find('.euiCard').should('have.length', 3);
cy.getBySel(INTEGRATIONS_SEARCHBAR.REMOVE_BADGE_BUTTON).click();
cy.getBySel(INTEGRATIONS_SEARCHBAR.BADGE).should('not.exist');
});
});
8 changes: 7 additions & 1 deletion x-pack/plugins/fleet/cypress/screens/integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ export const LATEST_VERSION = 'epmSettings.latestVersionTitle';
export const INSTALLED_VERSION = 'epmSettings.installedVersionTitle';

export const PACKAGE_VERSION = 'packageVersionText';
export const INTEGRATIONS_SEARCHBAR_INPUT = 'epmList.searchBar';
export const INTEGRATION_LIST = 'epmList.integrationCards';
export const INTEGRATIONS_SEARCHBAR = {
INPUT: 'epmList.searchBar',
BADGE: 'epmList.categoryBadge',
REMOVE_BADGE_BUTTON: 'epmList.categoryBadge.closeBtn',
};

export const SETTINGS = {
INSTALL_ASSETS_BTN: 'installAssetsButton',
Expand All @@ -33,3 +38,4 @@ export const SETTINGS = {
export const INTEGRATION_POLICIES_UPGRADE_CHECKBOX = 'epmDetails.upgradePoliciesCheckbox';

export const getIntegrationCard = (integration: string) => `integration-card:epr:${integration}`;
export const getIntegrationCategories = (category: string) => `epmList.categories.${category}`;
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import {
EuiLink,
EuiSpacer,
EuiTitle,
EuiSearchBar,
EuiFieldSearch,
EuiText,
EuiBadge,
useEuiTheme,
EuiIcon,
EuiScreenReaderOnly,
} from '@elastic/eui';

import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -69,6 +71,7 @@ export const PackageListGrid: FunctionComponent<Props> = ({
const menuRef = useRef<HTMLDivElement>(null);
const [isSticky, setIsSticky] = useState(false);
const [windowScrollY] = useState(window.scrollY);
const { euiTheme } = useEuiTheme();

useEffect(() => {
const menuRefCurrent = menuRef.current;
Expand All @@ -81,17 +84,10 @@ export const PackageListGrid: FunctionComponent<Props> = ({
return () => window.removeEventListener('scroll', onScroll);
}, [windowScrollY, isSticky]);

const onQueryChange = ({
queryText,
error,
}: {
queryText: string;
error: { message: string } | null;
}) => {
if (!error) {
onSearchChange(queryText);
setSearchTerm(queryText);
}
const onQueryChange = (e: any) => {
const queryText = e.target.value;
setSearchTerm(queryText);
onSearchChange(queryText);
};

const resetQuery = () => {
Expand Down Expand Up @@ -128,37 +124,64 @@ export const PackageListGrid: FunctionComponent<Props> = ({
<>
{featuredList}
<div ref={menuRef}>
<EuiFlexGroup alignItems="flexStart" gutterSize="xl">
<EuiFlexGroup
alignItems="flexStart"
gutterSize="xl"
data-test-subj="epmList.integrationCards"
>
<EuiFlexItem grow={1} className={isSticky ? 'kbnStickyMenu' : ''}>
{controlsContent}
</EuiFlexItem>
<EuiFlexItem grow={5}>
<EuiSearchBar
query={searchTerm || undefined}
box={{
'data-test-subj': 'epmList.searchBar',
placeholder: i18n.translate('xpack.fleet.epmList.searchPackagesPlaceholder', {
defaultMessage: 'Search for integrations',
}),
incremental: true,
}}
onChange={onQueryChange}
toolsRight={
<EuiFieldSearch
data-test-subj="epmList.searchBar"
placeholder={i18n.translate('xpack.fleet.epmList.searchPackagesPlaceholder', {
defaultMessage: 'Search for integrations',
})}
value={searchTerm}
onChange={(e) => onQueryChange(e)}
isClearable={true}
incremental={true}
fullWidth={true}
prepend={
selectedCategoryTitle ? (
<div>
<EuiBadge
color="accent"
iconType="cross"
iconSide="right"
iconOnClick={() => {
<EuiText
data-test-subj="epmList.categoryBadge"
size="xs"
style={{
display: 'flex',
alignItems: 'center',
fontWeight: euiTheme.font.weight.bold,
backgroundColor: euiTheme.colors.lightestShade,
}}
>
<EuiScreenReaderOnly>
<span>Searching category: </span>
</EuiScreenReaderOnly>
{selectedCategoryTitle}
<button
data-test-subj="epmList.categoryBadge.closeBtn"
onClick={() => {
setSelectedCategory('');
}}
iconOnClickAriaLabel="Remove category"
data-test-sub="epmList.categoryBadge"
aria-label="Remove filter"
style={{
padding: euiTheme.size.xs,
paddingTop: '2px',
}}
>
{selectedCategoryTitle}
</EuiBadge>
</div>
<EuiIcon
type="cross"
color="text"
size="s"
style={{
width: 'auto',
padding: 0,
backgroundColor: euiTheme.colors.lightestShade,
}}
/>
</button>
</EuiText>
) : undefined
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export function CategoryFacets({
categories.map((category) => {
return (
<EuiFacetButton
data-test-subj={`epmList.categories.${category.id}`}
isSelected={category.id === selectedCategory}
key={category.id}
id={category.id}
Expand Down

0 comments on commit 2be75d5

Please sign in to comment.