Fix spaces table rendering in IE (#23608) (#23703)

This fixes table rendering in IE where we display the Space Avatar alongside the Space Name. The solution is to[ render them in separate columns](https://github.com/elastic/kibana/issues/23546#issuecomment-425108806), instead of a single column.

Screenshots from IE:
![fixed spaces cutoff](https://user-images.githubusercontent.com/3493255/46208213-036db700-c2f8-11e8-9a43-67bb42b7c788.png)

![fixed spaces cutoff 2](https://user-images.githubusercontent.com/3493255/46208216-0668a780-c2f8-11e8-94e0-454c51d543e2.png)


Closes #23546
This commit is contained in:
Larry Gregory 2018-10-02 16:14:17 -04:00 committed by GitHub
parent aead3ef224
commit aeda9cfec9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 377 additions and 29 deletions

View file

@ -6,8 +6,6 @@
import {
EuiButtonIcon,
EuiFlexGroup,
EuiFlexItem,
// @ts-ignore
EuiInMemoryTable,
EuiText,
@ -91,33 +89,28 @@ export class PrivilegeSpaceTable extends Component<Props, State> {
public getTableColumns = (role: Role, availablePrivileges: KibanaPrivilege[] = []) => {
const columns: any[] = [
{
field: 'space',
name: '',
width: '50px',
sortable: true,
render: (space: Space | DeletedSpace) => {
if ('deleted' in space) {
return null;
}
return <SpaceAvatar space={space} size="s" />;
},
},
{
field: 'space',
name: 'Space',
width: this.props.readonly ? '75%' : '50%',
render: (space: Space | DeletedSpace) => {
let content;
if ('deleted' in space) {
content = [
<EuiFlexItem key={1}>
<EuiText color={'subdued'}>{space.id} (deleted)</EuiText>
</EuiFlexItem>,
];
return <EuiText color={'subdued'}>{space.id} (deleted)</EuiText>;
} else {
content = [
<EuiFlexItem key={1} grow={false}>
<SpaceAvatar space={space} size="s" />
</EuiFlexItem>,
<EuiFlexItem key={2}>
<EuiText>{space.name}</EuiText>
</EuiFlexItem>,
];
return <EuiText>{space.name}</EuiText>;
}
return (
<EuiFlexGroup gutterSize="s" responsive={false} alignItems={'center'}>
{content}
</EuiFlexGroup>
);
},
},
{

View file

@ -0,0 +1,260 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SpacesGridPage renders as expected 1`] = `
<EuiPage
className="spacesGridPage"
restrictWidth={true}
>
<EuiPageBody
restrictWidth={false}
>
<EuiPageContent
horizontalPosition="center"
panelPaddingSize="l"
>
<React.Fragment>
<EuiFlexGroup
alignItems="stretch"
component="div"
direction="row"
gutterSize="l"
justifyContent="spaceBetween"
responsive={true}
wrap={false}
>
<EuiFlexItem
component="div"
grow={false}
>
<EuiText
grow={true}
>
<h1>
Spaces
</h1>
</EuiText>
</EuiFlexItem>
<EuiFlexItem
component="div"
grow={false}
>
<EuiButton
color="primary"
fill={true}
iconSide="left"
onClick={[Function]}
type="button"
>
Create space
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer
size="xl"
/>
<EuiInMemoryTable
columns={
Array [
Object {
"field": "name",
"name": "",
"render": [Function],
"sortable": true,
"width": "50px",
},
Object {
"field": "name",
"name": "Space",
"render": [Function],
"sortable": true,
},
Object {
"field": "id",
"name": "Identifier",
"sortable": true,
},
Object {
"field": "description",
"name": "Description",
"sortable": true,
},
Object {
"actions": Array [
Object {
"color": "primary",
"description": "Edit this space.",
"icon": "pencil",
"name": "Edit",
"onClick": [Function],
"type": "icon",
},
Object {
"available": [Function],
"color": "danger",
"description": "Delete this space.",
"icon": "trash",
"name": "Delete",
"onClick": [Function],
"type": "icon",
},
],
"name": "Actions",
},
]
}
hasActions={true}
itemId="id"
items={Array []}
loading={true}
message="loading..."
pagination={true}
responsive={true}
search={
Object {
"box": Object {
"placeholder": "Search",
},
}
}
sorting={false}
/>
</React.Fragment>
</EuiPageContent>
<Component
userProfile={
UserProfileClass {
"capabilities": Object {
"manageSpaces": true,
},
}
}
/>
</EuiPageBody>
</EuiPage>
`;
exports[`SpacesGridPage renders the list of spaces 1`] = `
Array [
<Component
size="s"
space={
Object {
"_reserved": true,
"id": "default",
"name": "Default",
}
}
>
<EuiAvatar
color="#461A0A"
data-test-subj="space-avatar-default"
initials="D"
initialsLength={2}
name="Default"
size="s"
type="space"
>
<div
aria-label="Default"
className="euiAvatar euiAvatar--s euiAvatar--space"
data-test-subj="space-avatar-default"
style={
Object {
"backgroundColor": "#461A0A",
"backgroundImage": "none",
"color": "#FFFFFF",
}
}
title="Default"
>
<span
aria-hidden="true"
>
D
</span>
</div>
</EuiAvatar>
</Component>,
<Component
size="s"
space={
Object {
"id": "custom-1",
"name": "Custom 1",
}
}
>
<EuiAvatar
color="#BFA180"
data-test-subj="space-avatar-custom-1"
initials="C1"
initialsLength={2}
name="Custom 1"
size="s"
type="space"
>
<div
aria-label="Custom 1"
className="euiAvatar euiAvatar--s euiAvatar--space"
data-test-subj="space-avatar-custom-1"
style={
Object {
"backgroundColor": "#BFA180",
"backgroundImage": "none",
"color": "#000000",
}
}
title="Custom 1"
>
<span
aria-hidden="true"
>
C1
</span>
</div>
</EuiAvatar>
</Component>,
<Component
size="s"
space={
Object {
"color": "#ABCDEF",
"description": "my description here",
"id": "custom-2",
"initials": "LG",
"name": "Custom 2",
}
}
>
<EuiAvatar
color="#ABCDEF"
data-test-subj="space-avatar-custom-2"
initials="LG"
initialsLength={2}
name="Custom 2"
size="s"
type="space"
>
<div
aria-label="Custom 2"
className="euiAvatar euiAvatar--s euiAvatar--space"
data-test-subj="space-avatar-custom-2"
style={
Object {
"backgroundColor": "#ABCDEF",
"backgroundImage": "none",
"color": "#000000",
}
}
title="Custom 2"
>
<span
aria-hidden="true"
>
LG
</span>
</div>
</EuiAvatar>
</Component>,
]
`;

View file

@ -204,6 +204,23 @@ export class SpacesGridPage extends Component<Props, State> {
public getColumnConfig() {
return [
{
field: 'name',
name: '',
width: '50px',
sortable: true,
render: (value: string, record: Space) => {
return (
<EuiLink
onClick={() => {
this.onEditSpaceClick(record);
}}
>
<SpaceAvatar space={record} size="s" />
</EuiLink>
);
},
},
{
field: 'name',
name: 'Space',
@ -215,14 +232,7 @@ export class SpacesGridPage extends Component<Props, State> {
this.onEditSpaceClick(record);
}}
>
<EuiFlexGroup gutterSize="s" responsive={false} alignItems={'center'}>
<EuiFlexItem grow={false}>
<SpaceAvatar space={record} size="s" />
</EuiFlexItem>
<EuiFlexItem>
<EuiText>{record.name}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
{value}
</EuiLink>
);
},

View file

@ -0,0 +1,85 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { mount, shallow } from 'enzyme';
import React from 'react';
import { UserProfileProvider } from '../../../../../xpack_main/public/services/user_profile';
import { SpaceAvatar } from '../../../components';
import { SpacesManager } from '../../../lib';
import { SpacesNavState } from '../../nav_control';
import { SpacesGridPage } from './spaces_grid_page';
const buildUserProfile = (canManageSpaces: boolean) => {
return UserProfileProvider({ manageSpaces: canManageSpaces });
};
const spaces = [
{
id: 'default',
name: 'Default',
_reserved: true,
},
{
id: 'custom-1',
name: 'Custom 1',
},
{
id: 'custom-2',
name: 'Custom 2',
initials: 'LG',
color: '#ABCDEF',
description: 'my description here',
},
];
const mockHttp = {
get: jest.fn(async () => ({
data: spaces,
})),
};
const mockChrome = {
addBasePath: (path: string) => path,
};
const spacesNavState: SpacesNavState = {
getActiveSpace: () => spaces[0],
refreshSpacesList: jest.fn(),
};
const spacesManager = new SpacesManager(mockHttp, mockChrome, '');
describe('SpacesGridPage', () => {
it('renders as expected', () => {
expect(
shallow(
<SpacesGridPage
spacesManager={spacesManager}
spacesNavState={spacesNavState}
userProfile={buildUserProfile(true)}
/>
)
).toMatchSnapshot();
});
it('renders the list of spaces', async () => {
const wrapper = mount(
<SpacesGridPage
spacesManager={spacesManager}
spacesNavState={spacesNavState}
userProfile={buildUserProfile(true)}
/>
);
// allow spacesManager to load spaces
await Promise.resolve();
wrapper.update();
await Promise.resolve();
wrapper.update();
expect(wrapper.find(SpaceAvatar)).toHaveLength(spaces.length);
expect(wrapper.find(SpaceAvatar)).toMatchSnapshot();
});
});