[data view mgmt] Spaces list can expand and contract (#127101)

* data view spaces list is limited and can expand and contract AND it has a proper click target


Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Matthew Kime 2022-03-14 13:12:08 -05:00 committed by GitHub
parent 9739c5fa15
commit b0ae7f004b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 15 deletions

View file

@ -8,7 +8,6 @@
import React, { FC, useState } from 'react';
import { EuiButtonEmpty } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type {
SpacesPluginStart,
@ -33,7 +32,6 @@ export const SpacesList: FC<Props> = ({ spacesApi, spaceIds, id, title, refresh
function onClose() {
setShowFlyout(false);
refresh();
}
const LazySpaceList = spacesApi.ui.components.getSpaceList;
@ -47,18 +45,18 @@ export const SpacesList: FC<Props> = ({ spacesApi, spaceIds, id, title, refresh
title,
noun,
},
onUpdate: refresh,
onClose,
};
return (
<>
<EuiButtonEmpty
onClick={() => setShowFlyout(true)}
style={{ height: 'auto' }}
data-test-subj="manageSpacesButton"
>
<LazySpaceList namespaces={spaceIds} displayLimit={0} behaviorContext="outside-space" />
</EuiButtonEmpty>
<LazySpaceList
namespaces={spaceIds}
displayLimit={8}
behaviorContext="outside-space"
listOnClick={() => setShowFlyout(true)}
/>
{showFlyout && <LazyShareToSpaceFlyout {...shareToSpaceFlyoutProps} />}
</>
);

View file

@ -33,4 +33,19 @@ export interface SpaceAvatarProps {
* Default value is false.
*/
isDisabled?: boolean;
/**
* Callback to be invoked when the avatar is clicked.
*/
onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
/**
* Callback to be invoked when the avatar is clicked via keyboard.
*/
onKeyPress?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
/**
* Style props for the avatar.
*/
style?: React.CSSProperties;
}

View file

@ -80,6 +80,9 @@ describe('SpaceListInternal', () => {
function getButton(wrapper: ReactWrapper) {
return wrapper.find('EuiButtonEmpty');
}
async function getListClickTarget(wrapper: ReactWrapper) {
return (await wrapper.find('[data-test-subj="space-avatar-alpha"]')).first();
}
describe('using default properties', () => {
describe('with only the active space', () => {
@ -235,15 +238,18 @@ describe('SpaceListInternal', () => {
const { spaces, namespaces } = getSpaceData(8);
it('with displayLimit=0, shows badges without button', async () => {
const props = { namespaces: [...namespaces, '?'], displayLimit: 0 };
const props = { namespaces: [...namespaces, '?'], displayLimit: 0, listOnClick: jest.fn() };
const wrapper = await createSpaceList({ spaces, props });
expect(getListText(wrapper)).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', '+1']);
expect(getButton(wrapper)).toHaveLength(0);
(await getListClickTarget(wrapper)).simulate('click');
expect(props.listOnClick).toHaveBeenCalledTimes(1);
});
it('with displayLimit=1, shows badges with button', async () => {
const props = { namespaces: [...namespaces, '?'], displayLimit: 1 };
const props = { namespaces: [...namespaces, '?'], displayLimit: 1, listOnClick: jest.fn() };
const wrapper = await createSpaceList({ spaces, props });
expect(getListText(wrapper)).toEqual(['A']);
@ -257,6 +263,9 @@ describe('SpaceListInternal', () => {
const badgeText = getListText(wrapper);
expect(badgeText).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', '+1']);
expect(button.text()).toEqual('show less');
(await getListClickTarget(wrapper)).simulate('click');
expect(props.listOnClick).toHaveBeenCalledTimes(1);
});
it('with displayLimit=7, shows badges with button', async () => {

View file

@ -43,6 +43,7 @@ export const SpaceListInternal = ({
namespaces,
displayLimit = DEFAULT_DISPLAY_LIMIT,
behaviorContext,
listOnClick = () => {},
}: SpaceListProps) => {
const { spacesDataPromise } = useSpaces();
@ -103,14 +104,22 @@ export const SpaceListInternal = ({
if (displayLimit && authorizedSpaceTargets.length > displayLimit) {
button = isExpanded ? (
<EuiButtonEmpty size="xs" onClick={() => setIsExpanded(false)}>
<EuiButtonEmpty
size="xs"
onClick={() => setIsExpanded(false)}
style={{ alignSelf: 'center' }}
>
<FormattedMessage
id="xpack.spaces.spaceList.showLessSpacesLink"
defaultMessage="show less"
/>
</EuiButtonEmpty>
) : (
<EuiButtonEmpty size="xs" onClick={() => setIsExpanded(true)}>
<EuiButtonEmpty
size="xs"
onClick={() => setIsExpanded(true)}
style={{ alignSelf: 'center' }}
>
<FormattedMessage
id="xpack.spaces.spaceList.showMoreSpacesLink"
defaultMessage="+{count} more"
@ -147,7 +156,14 @@ export const SpaceListInternal = ({
const isDisabled = space.isFeatureDisabled;
return (
<EuiFlexItem grow={false} key={space.id}>
<LazySpaceAvatar space={space} isDisabled={isDisabled} size={'s'} />
<LazySpaceAvatar
space={space}
isDisabled={isDisabled}
size={'s'}
onClick={listOnClick}
onKeyPress={listOnClick}
style={{ cursor: 'pointer' }}
/>
</EuiFlexItem>
);
})}

View file

@ -28,4 +28,8 @@ export interface SpaceListProps {
* the active space.
*/
behaviorContext?: 'within-space' | 'outside-space';
/**
* Click handler for spaces list, specifically excluding expand and contract buttons.
*/
listOnClick?: () => void;
}

View file

@ -42,7 +42,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickKibanaIndexPatterns();
// click manage spaces on first entry
await (await testSubjects.findAll('manageSpacesButton', 10000))[0].click();
// first avatar is in header, so we want the second one
await (await testSubjects.findAll('space-avatar-default', 1000))[1].click();
// select custom space
await testSubjects.click('sts-space-selector-row-custom_space');