mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Translate Spaces component (#24411)
* Translate Spaces component * fix one little error * update Spaces component * update translation of Spaces components * Update snapshots * update Space translation - intl type * update Space translation - remove view/views id namespace * rename ids * use testing helper functions instead of shallow, render, mount from enzyme * fix unit tests * fix ts path for enzyme test helpers * fix path to enzyme helpers test functions * Update snapshots * fix path to enzyme test helpers * Remove unused dependency.
This commit is contained in:
parent
1155b81b4f
commit
fb6be4caed
46 changed files with 797 additions and 219 deletions
|
@ -24,7 +24,8 @@ export function createJestConfig({
|
|||
"^ui/(.*)": `${kibanaDirectory}/src/ui/public/$1`,
|
||||
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
|
||||
`${kibanaDirectory}/src/dev/jest/mocks/file_mock.js`,
|
||||
"\\.(css|less|scss)$": `${kibanaDirectory}/src/dev/jest/mocks/style_mock.js`
|
||||
"\\.(css|less|scss)$": `${kibanaDirectory}/src/dev/jest/mocks/style_mock.js`,
|
||||
"^test_utils/enzyme_helpers": `${xPackKibanaDirectory}/test_utils/enzyme_helpers.tsx`
|
||||
},
|
||||
setupFiles: [
|
||||
`${kibanaDirectory}/src/dev/jest/setup/babel_polyfill.js`,
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
|
||||
import { EuiFlyout, EuiLink } from '@elastic/eui';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { ImpactedSpacesFlyout } from './impacted_spaces_flyout';
|
||||
import { PrivilegeSpaceTable } from './privilege_space_table';
|
||||
|
||||
|
@ -52,16 +52,16 @@ const buildProps = (customProps = {}) => {
|
|||
|
||||
describe('<ImpactedSpacesFlyout>', () => {
|
||||
it('renders without crashing', () => {
|
||||
expect(shallow(<ImpactedSpacesFlyout {...buildProps()} />)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(<ImpactedSpacesFlyout {...buildProps()} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('does not immediately show the flyout', () => {
|
||||
const wrapper = mount(<ImpactedSpacesFlyout {...buildProps()} />);
|
||||
const wrapper = mountWithIntl(<ImpactedSpacesFlyout {...buildProps()} />);
|
||||
expect(wrapper.find(EuiFlyout)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('shows the flyout after clicking the link', () => {
|
||||
const wrapper = mount(<ImpactedSpacesFlyout {...buildProps()} />);
|
||||
const wrapper = mountWithIntl(<ImpactedSpacesFlyout {...buildProps()} />);
|
||||
wrapper.find(EuiLink).simulate('click');
|
||||
expect(wrapper.find(EuiFlyout)).toHaveLength(1);
|
||||
});
|
||||
|
@ -82,7 +82,7 @@ describe('<ImpactedSpacesFlyout>', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const wrapper = shallow(<ImpactedSpacesFlyout {...props} />);
|
||||
const wrapper = shallowWithIntl(<ImpactedSpacesFlyout {...props} />);
|
||||
wrapper.find(EuiLink).simulate('click');
|
||||
|
||||
const table = wrapper.find(PrivilegeSpaceTable);
|
||||
|
@ -112,7 +112,7 @@ describe('<ImpactedSpacesFlyout>', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const wrapper = shallow(<ImpactedSpacesFlyout {...props} />);
|
||||
const wrapper = shallowWithIntl(<ImpactedSpacesFlyout {...props} />);
|
||||
wrapper.find(EuiLink).simulate('click');
|
||||
|
||||
const table = wrapper.find(PrivilegeSpaceTable);
|
||||
|
@ -141,7 +141,7 @@ describe('<ImpactedSpacesFlyout>', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const wrapper = shallow(<ImpactedSpacesFlyout {...props} />);
|
||||
const wrapper = shallowWithIntl(<ImpactedSpacesFlyout {...props} />);
|
||||
wrapper.find(EuiLink).simulate('click');
|
||||
|
||||
const table = wrapper.find(PrivilegeSpaceTable);
|
||||
|
|
|
@ -11,6 +11,10 @@ exports[`ManageSpacesButton renders as expected 1`] = `
|
|||
size="s"
|
||||
type="button"
|
||||
>
|
||||
Manage spaces
|
||||
<FormattedMessage
|
||||
defaultMessage="Manage spaces"
|
||||
id="xpack.spaces.manageSpacesButton.manageSpacesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
`;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { UserProfileProvider } from '../../../xpack_main/public/services/user_profile';
|
||||
import { ManageSpacesButton } from './manage_spaces_button';
|
||||
|
||||
|
@ -15,11 +15,11 @@ const buildUserProfile = (canManageSpaces: boolean) => {
|
|||
describe('ManageSpacesButton', () => {
|
||||
it('renders as expected', () => {
|
||||
const component = <ManageSpacesButton userProfile={buildUserProfile(true)} />;
|
||||
expect(shallow(component)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`doesn't render if user profile forbids managing spaces`, () => {
|
||||
const component = <ManageSpacesButton userProfile={buildUserProfile(false)} />;
|
||||
expect(shallow(component)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiButton } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { Component, CSSProperties } from 'react';
|
||||
import { UserProfile } from '../../../xpack_main/public/services/user_profile';
|
||||
import { MANAGE_SPACES_URL } from '../lib/constants';
|
||||
|
@ -32,7 +33,10 @@ export class ManageSpacesButton extends Component<Props, {}> {
|
|||
onClick={this.navigateToManageSpaces}
|
||||
style={this.props.style}
|
||||
>
|
||||
Manage spaces
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.manageSpacesButton.manageSpacesButtonLabel"
|
||||
defaultMessage="Manage spaces"
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
|
||||
import { IHttpResponse } from 'angular';
|
||||
|
@ -66,8 +67,12 @@ export class SpacesManager extends EventEmitter {
|
|||
|
||||
public _displayError() {
|
||||
toastNotifications.addDanger({
|
||||
title: 'Unable to change your Space',
|
||||
text: 'please try again later',
|
||||
title: i18n.translate('xpack.spaces.spacesManager.unableToChangeSpaceWarningTitle', {
|
||||
defaultMessage: 'Unable to change your Space',
|
||||
}),
|
||||
text: i18n.translate('xpack.spaces.spacesManager.unableToChangeSpaceWarningDescription', {
|
||||
defaultMessage: 'please try again later',
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,15 @@ exports[`ConfirmDeleteModal renders as expected 1`] = `
|
|||
<EuiModalHeaderTitle
|
||||
data-test-subj="confirmModalTitleText"
|
||||
>
|
||||
Delete space
|
||||
'My Space'
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete space {spaceName}"
|
||||
id="xpack.spaces.management.confirmDeleteModal.confirmDeleteSpaceButtonLabel"
|
||||
values={
|
||||
Object {
|
||||
"spaceName": "'My Space'",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiModalHeaderTitle>
|
||||
</EuiModalHeader>
|
||||
<EuiModalBody>
|
||||
|
@ -22,12 +29,21 @@ exports[`ConfirmDeleteModal renders as expected 1`] = `
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Deleting a space permanently removes the space and
|
||||
|
||||
<strong>
|
||||
all of its contents
|
||||
</strong>
|
||||
. You can't undo this action.
|
||||
<FormattedMessage
|
||||
defaultMessage="Deleting a space permanently removes the space and {allContents}. You can't undo this action."
|
||||
id="xpack.spaces.management.confirmDeleteModal.deletingSpaceWarningMessage"
|
||||
values={
|
||||
Object {
|
||||
"allContents": <strong>
|
||||
<FormattedMessage
|
||||
defaultMessage="all of its contents"
|
||||
id="xpack.spaces.management.confirmDeleteModal.allContentsText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</strong>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
<EuiFormRow
|
||||
describedByIds={Array []}
|
||||
|
@ -54,15 +70,21 @@ exports[`ConfirmDeleteModal renders as expected 1`] = `
|
|||
grow={true}
|
||||
size="m"
|
||||
>
|
||||
You are about to delete your current space
|
||||
<span>
|
||||
(
|
||||
<strong>
|
||||
My Space
|
||||
</strong>
|
||||
)
|
||||
</span>
|
||||
. You will be redirected to choose a different space if you continue.
|
||||
<FormattedMessage
|
||||
defaultMessage="You are about to delete your current space {name}. You will be redirected to choose a different space if you continue."
|
||||
id="xpack.spaces.management.confirmDeleteModal.redirectAfterDeletingCurrentSpaceWarningMessage"
|
||||
values={
|
||||
Object {
|
||||
"name": <span>
|
||||
(
|
||||
<strong>
|
||||
My Space
|
||||
</strong>
|
||||
)
|
||||
</span>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiCallOut>
|
||||
</EuiText>
|
||||
|
@ -76,7 +98,11 @@ exports[`ConfirmDeleteModal renders as expected 1`] = `
|
|||
onClick={[MockFunction]}
|
||||
type="button"
|
||||
>
|
||||
Cancel
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel"
|
||||
id="xpack.spaces.management.confirmDeleteModal.cancelButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
<EuiButton
|
||||
color="danger"
|
||||
|
@ -87,7 +113,11 @@ exports[`ConfirmDeleteModal renders as expected 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete space and all contents
|
||||
<FormattedMessage
|
||||
defaultMessage=" Delete space and all contents"
|
||||
id="xpack.spaces.management.confirmDeleteModal.deleteSpaceAndAllContentsButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiModalFooter>
|
||||
</EuiModal>
|
||||
|
|
|
@ -6,14 +6,22 @@ exports[`UnauthorizedPrompt renders as expected 1`] = `
|
|||
<p
|
||||
data-test-subj="permissionDeniedMessage"
|
||||
>
|
||||
You do not have permission to manage spaces.
|
||||
<FormattedMessage
|
||||
defaultMessage="You do not have permission to manage spaces."
|
||||
id="xpack.spaces.management.unauthorizedPrompt.permissionDeniedDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
iconColor="danger"
|
||||
iconType="spacesApp"
|
||||
title={
|
||||
<h2>
|
||||
Permission denied
|
||||
<FormattedMessage
|
||||
defaultMessage="Permission denied"
|
||||
id="xpack.spaces.management.unauthorizedPrompt.permissionDeniedTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -11,11 +11,17 @@ exports[`AdvancedSettingsSubtitle renders as expected 1`] = `
|
|||
size="m"
|
||||
title={
|
||||
<p>
|
||||
The settings on this page apply to the
|
||||
<strong>
|
||||
My Space
|
||||
</strong>
|
||||
space, unless otherwise specified.
|
||||
<FormattedMessage
|
||||
defaultMessage="The settings on this page apply to the {spaceName} space, unless otherwise specified."
|
||||
id="xpack.spaces.management.advancedSettingsSubtitle.applyingSettingsOnPageToSpaceDescription"
|
||||
values={
|
||||
Object {
|
||||
"spaceName": <strong>
|
||||
My Space
|
||||
</strong>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { AdvancedSettingsSubtitle } from './advanced_settings_subtitle';
|
||||
|
||||
describe('AdvancedSettingsSubtitle', () => {
|
||||
|
@ -13,6 +13,6 @@ describe('AdvancedSettingsSubtitle', () => {
|
|||
id: 'my-space',
|
||||
name: 'My Space',
|
||||
};
|
||||
expect(shallow(<AdvancedSettingsSubtitle space={space} />)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(<AdvancedSettingsSubtitle space={space} />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { Fragment } from 'react';
|
||||
import { Space } from '../../../../../common/model/space';
|
||||
|
||||
|
@ -20,8 +21,13 @@ export const AdvancedSettingsSubtitle = (props: Props) => (
|
|||
iconType="spacesApp"
|
||||
title={
|
||||
<p>
|
||||
The settings on this page apply to the <strong>{props.space.name}</strong> space, unless
|
||||
otherwise specified.
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.advancedSettingsSubtitle.applyingSettingsOnPageToSpaceDescription"
|
||||
defaultMessage="The settings on this page apply to the {spaceName} space, unless otherwise specified."
|
||||
values={{
|
||||
spaceName: <strong>{props.space.name}</strong>,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -39,7 +39,11 @@ exports[`AdvancedSettingsTitle renders as expected 1`] = `
|
|||
<h1
|
||||
data-test-subj="managementSettingsTitle"
|
||||
>
|
||||
Settings
|
||||
<FormattedMessage
|
||||
defaultMessage="Settings"
|
||||
id="xpack.spaces.management.advancedSettingsTitle.settingsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { AdvancedSettingsTitle } from './advanced_settings_title';
|
||||
|
||||
describe('AdvancedSettingsTitle', () => {
|
||||
|
@ -13,6 +13,6 @@ describe('AdvancedSettingsTitle', () => {
|
|||
id: 'my-space',
|
||||
name: 'My Space',
|
||||
};
|
||||
expect(shallow(<AdvancedSettingsTitle space={space} />)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(<AdvancedSettingsTitle space={space} />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { Space } from '../../../../../common/model/space';
|
||||
import { SpaceAvatar } from '../../../../components';
|
||||
|
@ -20,7 +21,12 @@ export const AdvancedSettingsTitle = (props: Props) => (
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem style={{ marginLeft: '10px' }}>
|
||||
<EuiText>
|
||||
<h1 data-test-subj="managementSettingsTitle">Settings</h1>
|
||||
<h1 data-test-subj="managementSettingsTitle">
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.advancedSettingsTitle.settingsTitle"
|
||||
defaultMessage="Settings"
|
||||
/>
|
||||
</h1>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* 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 { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { SpacesManager } from '../../../lib';
|
||||
import { SpacesNavState } from '../../nav_control';
|
||||
import { ConfirmDeleteModal } from './confirm_delete_modal';
|
||||
|
@ -38,13 +38,14 @@ describe('ConfirmDeleteModal', () => {
|
|||
const onConfirm = jest.fn();
|
||||
|
||||
expect(
|
||||
shallow(
|
||||
<ConfirmDeleteModal
|
||||
shallowWithIntl(
|
||||
<ConfirmDeleteModal.WrappedComponent
|
||||
space={space}
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
intl={null as any}
|
||||
/>
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
|
@ -71,13 +72,14 @@ describe('ConfirmDeleteModal', () => {
|
|||
const onCancel = jest.fn();
|
||||
const onConfirm = jest.fn();
|
||||
|
||||
const wrapper = mount(
|
||||
<ConfirmDeleteModal
|
||||
const wrapper = mountWithIntl(
|
||||
<ConfirmDeleteModal.WrappedComponent
|
||||
space={space}
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
EuiOverlayMask,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import { SpacesNavState } from 'plugins/spaces/views/nav_control';
|
||||
import React, { ChangeEvent, Component } from 'react';
|
||||
import { Space } from '../../../../common/model/space';
|
||||
|
@ -31,6 +32,7 @@ interface Props {
|
|||
spacesNavState: SpacesNavState;
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -39,7 +41,7 @@ interface State {
|
|||
deleteInProgress: boolean;
|
||||
}
|
||||
|
||||
export class ConfirmDeleteModal extends Component<Props, State> {
|
||||
class ConfirmDeleteModalUI extends Component<Props, State> {
|
||||
public state = {
|
||||
confirmSpaceName: '',
|
||||
error: null,
|
||||
|
@ -47,7 +49,7 @@ export class ConfirmDeleteModal extends Component<Props, State> {
|
|||
};
|
||||
|
||||
public render() {
|
||||
const { space, spacesNavState, onCancel } = this.props;
|
||||
const { space, spacesNavState, onCancel, intl } = this.props;
|
||||
|
||||
let warning = null;
|
||||
if (isDeletingCurrentSpace(space, spacesNavState)) {
|
||||
|
@ -59,8 +61,11 @@ export class ConfirmDeleteModal extends Component<Props, State> {
|
|||
warning = (
|
||||
<EuiCallOut color="warning">
|
||||
<EuiText>
|
||||
You are about to delete your current space {name}. You will be redirected to choose a
|
||||
different space if you continue.
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.confirmDeleteModal.redirectAfterDeletingCurrentSpaceWarningMessage"
|
||||
defaultMessage="You are about to delete your current space {name}. You will be redirected to choose a different space if you continue."
|
||||
values={{ name }}
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiCallOut>
|
||||
);
|
||||
|
@ -74,20 +79,44 @@ export class ConfirmDeleteModal extends Component<Props, State> {
|
|||
<EuiModal onClose={onCancel} className={'spcConfirmDeleteModal'}>
|
||||
<EuiModalHeader>
|
||||
<EuiModalHeaderTitle data-test-subj="confirmModalTitleText">
|
||||
Delete space {`'${space.name}'`}
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.confirmDeleteModal.confirmDeleteSpaceButtonLabel"
|
||||
defaultMessage="Delete space {spaceName}"
|
||||
values={{
|
||||
spaceName: "'" + space.name + "'",
|
||||
}}
|
||||
/>
|
||||
</EuiModalHeaderTitle>
|
||||
</EuiModalHeader>
|
||||
<EuiModalBody>
|
||||
<EuiText data-test-subj="confirmModalBodyText">
|
||||
<p>
|
||||
Deleting a space permanently removes the space and{' '}
|
||||
<strong>all of its contents</strong>. You can't undo this action.
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.confirmDeleteModal.deletingSpaceWarningMessage"
|
||||
defaultMessage="Deleting a space permanently removes the space and {allContents}. You can't undo this action."
|
||||
values={{
|
||||
allContents: (
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.confirmDeleteModal.allContentsText"
|
||||
defaultMessage="all of its contents"
|
||||
/>
|
||||
</strong>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
|
||||
<EuiFormRow
|
||||
label={'Confirm space name'}
|
||||
label={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.confirmDeleteModal.confirmSpaceNameFormRowLabel',
|
||||
defaultMessage: 'Confirm space name',
|
||||
})}
|
||||
isInvalid={!!this.state.error}
|
||||
error={'Space names do not match.'}
|
||||
error={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.confirmDeleteModal.spaceNamesDoNoMatchErrorMessage',
|
||||
defaultMessage: 'Space names do not match.',
|
||||
})}
|
||||
>
|
||||
<EuiFieldText
|
||||
value={this.state.confirmSpaceName}
|
||||
|
@ -105,7 +134,10 @@ export class ConfirmDeleteModal extends Component<Props, State> {
|
|||
onClick={onCancel}
|
||||
isDisabled={this.state.deleteInProgress}
|
||||
>
|
||||
Cancel
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.confirmDeleteModal.cancelButtonLabel"
|
||||
defaultMessage="Cancel"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
|
||||
<EuiButton
|
||||
|
@ -115,7 +147,10 @@ export class ConfirmDeleteModal extends Component<Props, State> {
|
|||
color={'danger'}
|
||||
isLoading={this.state.deleteInProgress}
|
||||
>
|
||||
Delete space and all contents
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.confirmDeleteModal.deleteSpaceAndAllContentsButtonLabel"
|
||||
defaultMessage=" Delete space and all contents"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiModalFooter>
|
||||
</EuiModal>
|
||||
|
@ -165,3 +200,5 @@ export class ConfirmDeleteModal extends Component<Props, State> {
|
|||
function isDeletingCurrentSpace(space: Space, spacesNavState: SpacesNavState) {
|
||||
return space.id === spacesNavState.getActiveSpace().id;
|
||||
}
|
||||
|
||||
export const ConfirmDeleteModal = injectI18n(ConfirmDeleteModalUI);
|
||||
|
|
|
@ -13,16 +13,25 @@ exports[`SecureSpaceMessage renders if user profile allows security to be manage
|
|||
size="m"
|
||||
>
|
||||
<p>
|
||||
Want to assign a role to a space? Go to Management and select
|
||||
|
||||
<EuiLink
|
||||
color="primary"
|
||||
href="#/management/security/roles"
|
||||
type="button"
|
||||
>
|
||||
Roles
|
||||
</EuiLink>
|
||||
.
|
||||
<FormattedMessage
|
||||
defaultMessage="Want to assign a role to a space? Go to Management and select {rolesLink}."
|
||||
id="xpack.spaces.management.secureSpaceMessage.howToAssignRoleToSpaceDescription"
|
||||
values={
|
||||
Object {
|
||||
"rolesLink": <EuiLink
|
||||
color="primary"
|
||||
href="#/management/security/roles"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Roles"
|
||||
id="xpack.spaces.management.secureSpaceMessage.rolesLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { SecureSpaceMessage } from './secure_space_message';
|
||||
|
||||
describe('SecureSpaceMessage', () => {
|
||||
|
@ -18,7 +18,7 @@ describe('SecureSpaceMessage', () => {
|
|||
},
|
||||
};
|
||||
|
||||
expect(shallow(<SecureSpaceMessage userProfile={userProfile} />)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(<SecureSpaceMessage userProfile={userProfile} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`renders if user profile allows security to be managed`, () => {
|
||||
|
@ -31,6 +31,6 @@ describe('SecureSpaceMessage', () => {
|
|||
},
|
||||
};
|
||||
|
||||
expect(shallow(<SecureSpaceMessage userProfile={userProfile} />)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(<SecureSpaceMessage userProfile={userProfile} />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiLink, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { UserProfile } from 'plugins/xpack_main/services/user_profile';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
|
@ -19,8 +20,20 @@ export const SecureSpaceMessage = (props: Props) => {
|
|||
<EuiSpacer />
|
||||
<EuiText className="eui-textCenter">
|
||||
<p>
|
||||
Want to assign a role to a space? Go to Management and select{' '}
|
||||
<EuiLink href="#/management/security/roles">Roles</EuiLink>.
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.secureSpaceMessage.howToAssignRoleToSpaceDescription"
|
||||
defaultMessage="Want to assign a role to a space? Go to Management and select {rolesLink}."
|
||||
values={{
|
||||
rolesLink: (
|
||||
<EuiLink href="#/management/security/roles">
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.secureSpaceMessage.rolesLinkText"
|
||||
defaultMessage="Roles"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</Fragment>
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { UnauthorizedPrompt } from './unauthorized_prompt';
|
||||
|
||||
describe('UnauthorizedPrompt', () => {
|
||||
it('renders as expected', () => {
|
||||
expect(shallow(<UnauthorizedPrompt />)).toMatchSnapshot();
|
||||
expect(shallowWithIntl(<UnauthorizedPrompt />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,15 +5,28 @@
|
|||
*/
|
||||
|
||||
import { EuiEmptyPrompt } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
|
||||
export const UnauthorizedPrompt = () => (
|
||||
<EuiEmptyPrompt
|
||||
iconType="spacesApp"
|
||||
iconColor={'danger'}
|
||||
title={<h2>Permission denied</h2>}
|
||||
title={
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.unauthorizedPrompt.permissionDeniedTitle"
|
||||
defaultMessage="Permission denied"
|
||||
/>
|
||||
</h2>
|
||||
}
|
||||
body={
|
||||
<p data-test-subj="permissionDeniedMessage">You do not have permission to manage spaces.</p>
|
||||
<p data-test-subj="permissionDeniedMessage">
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.unauthorizedPrompt.permissionDeniedDescription"
|
||||
defaultMessage="You do not have permission to manage spaces."
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -16,7 +16,11 @@ exports[`renders without crashing 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Customize
|
||||
<FormattedMessage
|
||||
defaultMessage="Customize"
|
||||
id="xpack.spaces.management.customizeSpaceAvatar.customizeLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -10,7 +10,11 @@ exports[`DeleteSpacesButton renders as expected 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete space
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete space"
|
||||
id="xpack.spaces.management.deleteSpacesButton.deleteSpaceButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
|
|
@ -8,29 +8,50 @@ exports[`renders without crashing 1`] = `
|
|||
hasEmptyLabelSpace={false}
|
||||
helpText={
|
||||
<p>
|
||||
If the identifier is
|
||||
<strong>
|
||||
engineering
|
||||
</strong>
|
||||
, the Kibana URL is
|
||||
<br />
|
||||
https://my-kibana.example
|
||||
<strong>
|
||||
/s/engineering/
|
||||
</strong>
|
||||
app/kibana.
|
||||
<FormattedMessage
|
||||
defaultMessage="If the identifier is {engineeringIdentifier}, the Kibana URL is{nextLine}
|
||||
{engineeringKibanaUrl}."
|
||||
id="xpack.spaces.management.spaceIdentifier.kibanaURLForEngineeringIdentifierDescription"
|
||||
values={
|
||||
Object {
|
||||
"engineeringIdentifier": <strong>
|
||||
<FormattedMessage
|
||||
defaultMessage="engineering"
|
||||
id="xpack.spaces.management.spaceIdentifier.engineeringText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</strong>,
|
||||
"engineeringKibanaUrl": <React.Fragment>
|
||||
https://my-kibana.example
|
||||
<strong>
|
||||
/s/engineering/
|
||||
</strong>
|
||||
app/kibana
|
||||
</React.Fragment>,
|
||||
"nextLine": <br />,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
isInvalid={false}
|
||||
label={
|
||||
<p>
|
||||
URL identifier
|
||||
<FormattedMessage
|
||||
defaultMessage="URL identifier"
|
||||
id="xpack.spaces.management.spaceIdentifier.urlIdentifierLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
<EuiLink
|
||||
color="primary"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
[edit]
|
||||
<FormattedMessage
|
||||
defaultMessage="[edit]"
|
||||
id="xpack.spaces.management.spaceIdentifier.editSpaceLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
</p>
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
// @ts-ignore
|
||||
import { EuiColorPicker, EuiFieldText, EuiLink } from '@elastic/eui';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { CustomizeSpaceAvatar } from './customize_space_avatar';
|
||||
|
||||
const space = {
|
||||
|
@ -15,17 +15,23 @@ const space = {
|
|||
};
|
||||
|
||||
test('renders without crashing', () => {
|
||||
const wrapper = shallow(<CustomizeSpaceAvatar space={space} onChange={jest.fn()} />);
|
||||
const wrapper = shallowWithIntl(
|
||||
<CustomizeSpaceAvatar.WrappedComponent space={space} onChange={jest.fn()} intl={null as any} />
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('renders a "customize" link by default', () => {
|
||||
const wrapper = mount(<CustomizeSpaceAvatar space={space} onChange={jest.fn()} />);
|
||||
const wrapper = mountWithIntl(
|
||||
<CustomizeSpaceAvatar.WrappedComponent space={space} onChange={jest.fn()} intl={null as any} />
|
||||
);
|
||||
expect(wrapper.find(EuiLink)).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('shows customization fields when the "customize" link is clicked', () => {
|
||||
const wrapper = mount(<CustomizeSpaceAvatar space={space} onChange={jest.fn()} />);
|
||||
const wrapper = mountWithIntl(
|
||||
<CustomizeSpaceAvatar.WrappedComponent space={space} onChange={jest.fn()} intl={null as any} />
|
||||
);
|
||||
wrapper.find(EuiLink).simulate('click');
|
||||
|
||||
expect(wrapper.find(EuiLink)).toHaveLength(0);
|
||||
|
@ -43,7 +49,13 @@ test('invokes onChange callback when avatar is customized', () => {
|
|||
|
||||
const changeHandler = jest.fn();
|
||||
|
||||
const wrapper = mount(<CustomizeSpaceAvatar space={customizedSpace} onChange={changeHandler} />);
|
||||
const wrapper = mountWithIntl(
|
||||
<CustomizeSpaceAvatar.WrappedComponent
|
||||
space={customizedSpace}
|
||||
onChange={changeHandler}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
wrapper.find(EuiLink).simulate('click');
|
||||
|
||||
wrapper
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
// @ts-ignore
|
||||
import { EuiColorPicker, EuiFieldText, EuiFlexItem, EuiFormRow, EuiLink } from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import React, { ChangeEvent, Component, Fragment } from 'react';
|
||||
import { MAX_SPACE_INITIALS } from '../../../../common/constants';
|
||||
import { Space } from '../../../../common/model/space';
|
||||
|
@ -13,6 +14,7 @@ import { getSpaceColor, getSpaceInitials } from '../../../../common/space_attrib
|
|||
interface Props {
|
||||
space: Partial<Space>;
|
||||
onChange: (space: Partial<Space>) => void;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -21,7 +23,7 @@ interface State {
|
|||
pendingInitials?: string | null;
|
||||
}
|
||||
|
||||
export class CustomizeSpaceAvatar extends Component<Props, State> {
|
||||
class CustomizeSpaceAvatarUI extends Component<Props, State> {
|
||||
private initialsRef: HTMLInputElement | null = null;
|
||||
|
||||
constructor(props: Props) {
|
||||
|
@ -37,14 +39,19 @@ export class CustomizeSpaceAvatar extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public getCustomizeFields = () => {
|
||||
const { space } = this.props;
|
||||
const { space, intl } = this.props;
|
||||
|
||||
const { initialsHasFocus, pendingInitials } = this.state;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFormRow label={'Initials (2 max)'}>
|
||||
<EuiFormRow
|
||||
label={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.customizeSpaceAvatar.initialItemsFormRowLabel',
|
||||
defaultMessage: 'Initials (2 max)',
|
||||
})}
|
||||
>
|
||||
<EuiFieldText
|
||||
inputRef={this.initialsInputRef}
|
||||
name="spaceInitials"
|
||||
|
@ -56,7 +63,12 @@ export class CustomizeSpaceAvatar extends Component<Props, State> {
|
|||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiFormRow label={'Color'}>
|
||||
<EuiFormRow
|
||||
label={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.customizeSpaceAvatar.colorFormRowLabel',
|
||||
defaultMessage: 'Color',
|
||||
})}
|
||||
>
|
||||
<EuiColorPicker color={getSpaceColor(space)} onChange={this.onColorChange} />
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -97,7 +109,10 @@ export class CustomizeSpaceAvatar extends Component<Props, State> {
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiFormRow hasEmptyLabelSpace={true}>
|
||||
<EuiLink name="customize_space_link" onClick={this.showFields}>
|
||||
Customize
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.customizeSpaceAvatar.customizeLinkText"
|
||||
defaultMessage="Customize"
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -130,3 +145,5 @@ export class CustomizeSpaceAvatar extends Component<Props, State> {
|
|||
});
|
||||
};
|
||||
}
|
||||
|
||||
export const CustomizeSpaceAvatar = injectI18n(CustomizeSpaceAvatarUI);
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { SpacesManager } from '../../../lib';
|
||||
import { SpacesNavState } from '../../nav_control';
|
||||
import { DeleteSpacesButton } from './delete_spaces_button';
|
||||
|
@ -34,12 +34,13 @@ describe('DeleteSpacesButton', () => {
|
|||
refreshSpacesList: jest.fn(),
|
||||
};
|
||||
|
||||
const wrapper = shallow(
|
||||
<DeleteSpacesButton
|
||||
const wrapper = shallowWithIntl(
|
||||
<DeleteSpacesButton.WrappedComponent
|
||||
space={space}
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
onDelete={jest.fn()}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiButton, EuiButtonIcon, EuiButtonIconProps } from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import { SpacesNavState } from 'plugins/spaces/views/nav_control';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
// @ts-ignore
|
||||
|
@ -19,6 +20,7 @@ interface Props {
|
|||
spacesManager: SpacesManager;
|
||||
spacesNavState: SpacesNavState;
|
||||
onDelete: () => void;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -26,14 +28,20 @@ interface State {
|
|||
showConfirmRedirectModal: boolean;
|
||||
}
|
||||
|
||||
export class DeleteSpacesButton extends Component<Props, State> {
|
||||
class DeleteSpacesButtonUI extends Component<Props, State> {
|
||||
public state = {
|
||||
showConfirmDeleteModal: false,
|
||||
showConfirmRedirectModal: false,
|
||||
};
|
||||
|
||||
public render() {
|
||||
const buttonText = `Delete space`;
|
||||
const buttonText = (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.deleteSpacesButton.deleteSpaceButtonLabel"
|
||||
defaultMessage="Delete space"
|
||||
/>
|
||||
);
|
||||
const { intl } = this.props;
|
||||
|
||||
let ButtonComponent: any = EuiButton;
|
||||
|
||||
|
@ -49,7 +57,10 @@ export class DeleteSpacesButton extends Component<Props, State> {
|
|||
<ButtonComponent
|
||||
color={'danger'}
|
||||
onClick={this.onDeleteClick}
|
||||
aria-label={'Delete this space'}
|
||||
aria-label={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.deleteSpacesButton.deleteSpaceAriaLabel',
|
||||
defaultMessage: 'Delete this space',
|
||||
})}
|
||||
{...extraProps}
|
||||
>
|
||||
{buttonText}
|
||||
|
@ -88,21 +99,40 @@ export class DeleteSpacesButton extends Component<Props, State> {
|
|||
};
|
||||
|
||||
public deleteSpaces = async () => {
|
||||
const { spacesManager, space, spacesNavState } = this.props;
|
||||
const { spacesManager, space, spacesNavState, intl } = this.props;
|
||||
|
||||
try {
|
||||
await spacesManager.deleteSpace(space);
|
||||
} catch (error) {
|
||||
const { message: errorMessage = '' } = error.data || {};
|
||||
|
||||
toastNotifications.addDanger(`Error deleting space: ${errorMessage}`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage(
|
||||
{
|
||||
id: 'xpack.spaces.management.deleteSpacesButton.deleteSpaceErrorTitle',
|
||||
defaultMessage: 'Error deleting space: {errorMessage}',
|
||||
},
|
||||
{
|
||||
errorMessage,
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
showConfirmDeleteModal: false,
|
||||
});
|
||||
|
||||
const message = `Deleted "${space.name}" space.`;
|
||||
const message = intl.formatMessage(
|
||||
{
|
||||
id:
|
||||
'xpack.spaces.management.deleteSpacesButton.spaceSuccessfullyDeletedNotificationMessage',
|
||||
defaultMessage: 'Deleted {spaceName} space.',
|
||||
},
|
||||
{
|
||||
spaceName: space.name,
|
||||
}
|
||||
);
|
||||
|
||||
toastNotifications.addSuccess(message);
|
||||
|
||||
|
@ -113,3 +143,5 @@ export class DeleteSpacesButton extends Component<Props, State> {
|
|||
spacesNavState.refreshSpacesList();
|
||||
};
|
||||
}
|
||||
|
||||
export const DeleteSpacesButton = injectI18n(DeleteSpacesButtonUI);
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { mount } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { UserProfileProvider } from '../../../../../xpack_main/public/services/user_profile';
|
||||
import { SpacesManager } from '../../../lib';
|
||||
import { SpacesNavState } from '../../nav_control';
|
||||
|
@ -42,11 +42,12 @@ describe('ManageSpacePage', () => {
|
|||
|
||||
const userProfile = buildUserProfile(true);
|
||||
|
||||
const wrapper = mount(
|
||||
<ManageSpacePage
|
||||
const wrapper = mountWithIntl(
|
||||
<ManageSpacePage.WrappedComponent
|
||||
spacesManager={spacesManager}
|
||||
userProfile={userProfile}
|
||||
spacesNavState={spacesNavState}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
const nameInput = wrapper.find('input[name="name"]');
|
||||
|
@ -96,12 +97,13 @@ describe('ManageSpacePage', () => {
|
|||
|
||||
const userProfile = buildUserProfile(true);
|
||||
|
||||
const wrapper = mount(
|
||||
<ManageSpacePage
|
||||
const wrapper = mountWithIntl(
|
||||
<ManageSpacePage.WrappedComponent
|
||||
spaceId={'existing-space'}
|
||||
spacesManager={spacesManager}
|
||||
userProfile={userProfile}
|
||||
spacesNavState={spacesNavState}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
EuiSpacer,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import React, { ChangeEvent, Component, Fragment } from 'react';
|
||||
|
||||
import { SpacesNavState } from 'plugins/spaces/views/nav_control';
|
||||
|
@ -45,6 +46,7 @@ interface Props {
|
|||
spaceId?: string;
|
||||
userProfile: UserProfile;
|
||||
spacesNavState: SpacesNavState;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -56,7 +58,7 @@ interface State {
|
|||
};
|
||||
}
|
||||
|
||||
export class ManageSpacePage extends Component<Props, State> {
|
||||
class ManageSpacePageUI extends Component<Props, State> {
|
||||
private readonly validator: SpaceValidator;
|
||||
|
||||
constructor(props: Props) {
|
||||
|
@ -69,7 +71,7 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public componentDidMount() {
|
||||
const { spaceId, spacesManager } = this.props;
|
||||
const { spaceId, spacesManager, intl } = this.props;
|
||||
|
||||
if (spaceId) {
|
||||
spacesManager
|
||||
|
@ -85,7 +87,17 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
.catch(error => {
|
||||
const { message = '' } = error.data || {};
|
||||
|
||||
toastNotifications.addDanger(`Error loading space: ${message}`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage(
|
||||
{
|
||||
id: 'xpack.spaces.management.manageSpacePage.errorLoadingSpaceTitle',
|
||||
defaultMessage: 'Error loading space: {message}',
|
||||
},
|
||||
{
|
||||
message,
|
||||
}
|
||||
)
|
||||
);
|
||||
this.backToSpacesList();
|
||||
});
|
||||
} else {
|
||||
|
@ -113,14 +125,19 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
<div>
|
||||
<EuiLoadingSpinner size={'xl'} />{' '}
|
||||
<EuiTitle>
|
||||
<h1>Loading...</h1>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.manageSpacePage.loadingTitle"
|
||||
defaultMessage="Loading…"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
public getForm = () => {
|
||||
const { userProfile } = this.props;
|
||||
const { userProfile, intl } = this.props;
|
||||
|
||||
if (!userProfile.hasCapability('manageSpaces')) {
|
||||
return <UnauthorizedPrompt />;
|
||||
|
@ -134,16 +151,25 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiFormRow label="Name" {...this.validator.validateSpaceName(this.state.space)} fullWidth>
|
||||
<EuiFormRow
|
||||
label={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.manageSpacePage.nameFormRowLabel',
|
||||
defaultMessage: 'Name',
|
||||
})}
|
||||
{...this.validator.validateSpaceName(this.state.space)}
|
||||
fullWidth
|
||||
>
|
||||
<EuiFieldText
|
||||
name="name"
|
||||
placeholder={'Awesome space'}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.manageSpacePage.awesomeSpacePlaceholder',
|
||||
defaultMessage: 'Awesome space',
|
||||
})}
|
||||
value={name}
|
||||
onChange={this.onNameChange}
|
||||
fullWidth
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
||||
{name && (
|
||||
<Fragment>
|
||||
<EuiFlexGroup responsive={false}>
|
||||
|
@ -170,13 +196,19 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
)}
|
||||
|
||||
<EuiFormRow
|
||||
label="Description (optional)"
|
||||
label={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.editSpace.manageSpacePage.optionalDescriptionFormRowLabel',
|
||||
defaultMessage: 'Description (optional)',
|
||||
})}
|
||||
{...this.validator.validateSpaceDescription(this.state.space)}
|
||||
fullWidth
|
||||
>
|
||||
<EuiFieldText
|
||||
name="description"
|
||||
placeholder={'This is where the magic happens'}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.spaces.management.manageSpacePage.hereMagicHappensPlaceholder',
|
||||
defaultMessage: 'This is where the magic happens',
|
||||
})}
|
||||
value={description}
|
||||
onChange={this.onDescriptionChange}
|
||||
fullWidth
|
||||
|
@ -202,9 +234,19 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
|
||||
public getTitle = () => {
|
||||
if (this.editingExistingSpace()) {
|
||||
return `Edit space`;
|
||||
return (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.manageSpacePage.editSpaceTitle"
|
||||
defaultMessage="Edit space"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return `Create space`;
|
||||
return (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.manageSpacePage.createSpaceTitle"
|
||||
defaultMessage="Create space"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
public maybeGetSecureSpacesMessage = () => {
|
||||
|
@ -215,7 +257,17 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
};
|
||||
|
||||
public getFormButtons = () => {
|
||||
const saveText = this.editingExistingSpace() ? 'Update space' : 'Create space';
|
||||
const saveText = this.editingExistingSpace() ? (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.manageSpacePage.updateSpaceButtonLabel"
|
||||
defaultMessage="Update space"
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.manageSpacePage.createSpaceButtonLabel"
|
||||
defaultMessage="Create space"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<EuiFlexGroup responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -225,7 +277,10 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty onClick={this.backToSpacesList} data-test-subj="cancel-space-button">
|
||||
Cancel
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.manageSpacePage.cancelButtonLabel"
|
||||
defaultMessage="Cancel"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={true} />
|
||||
|
@ -314,6 +369,7 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
};
|
||||
|
||||
private performSave = () => {
|
||||
const { intl } = this.props;
|
||||
if (!this.state.space) {
|
||||
return;
|
||||
}
|
||||
|
@ -339,13 +395,34 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
action
|
||||
.then(() => {
|
||||
this.props.spacesNavState.refreshSpacesList();
|
||||
toastNotifications.addSuccess(`'${name}' was saved`);
|
||||
toastNotifications.addSuccess(
|
||||
intl.formatMessage(
|
||||
{
|
||||
id:
|
||||
'xpack.spaces.management.manageSpacePage.spaceSuccessfullySavedNotificationMessage',
|
||||
defaultMessage: '{name} was saved',
|
||||
},
|
||||
{
|
||||
name: `'${name}'`,
|
||||
}
|
||||
)
|
||||
);
|
||||
window.location.hash = `#/management/spaces/list`;
|
||||
})
|
||||
.catch(error => {
|
||||
const { message = '' } = error.data || {};
|
||||
|
||||
toastNotifications.addDanger(`Error saving space: ${message}`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage(
|
||||
{
|
||||
id: 'xpack.spaces.management.manageSpacePage.errorSavingSpaceTitle',
|
||||
defaultMessage: 'Error saving space: {message}',
|
||||
},
|
||||
{
|
||||
message,
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -355,3 +432,5 @@ export class ManageSpacePage extends Component<Props, State> {
|
|||
|
||||
private editingExistingSpace = () => !!this.props.spaceId;
|
||||
}
|
||||
|
||||
export const ManageSpacePage = injectI18n(ManageSpacePageUI);
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { ReservedSpaceBadge } from './reserved_space_badge';
|
||||
|
||||
const reservedSpace = {
|
||||
|
@ -21,11 +21,11 @@ const unreservedSpace = {
|
|||
};
|
||||
|
||||
test('it renders without crashing', () => {
|
||||
const wrapper = shallow(<ReservedSpaceBadge space={reservedSpace} />);
|
||||
const wrapper = shallowWithIntl(<ReservedSpaceBadge space={reservedSpace} />);
|
||||
expect(wrapper.find(EuiIcon)).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('it renders nothing for an unreserved space', () => {
|
||||
const wrapper = shallow(<ReservedSpaceBadge space={unreservedSpace} />);
|
||||
const wrapper = shallowWithIntl(<ReservedSpaceBadge space={unreservedSpace} />);
|
||||
expect(wrapper.find('*')).toHaveLength(0);
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import React from 'react';
|
||||
|
||||
import { EuiIcon, EuiToolTip } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { isReservedSpace } from '../../../../common';
|
||||
import { Space } from '../../../../common/model/space';
|
||||
|
||||
|
@ -19,7 +20,14 @@ export const ReservedSpaceBadge = (props: Props) => {
|
|||
|
||||
if (space && isReservedSpace(space)) {
|
||||
return (
|
||||
<EuiToolTip content={'Reserved spaces are built-in and can only be partially modified.'}>
|
||||
<EuiToolTip
|
||||
content={
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.reversedSpaceBadge.reversedSpacesCanBePartiallyModifiedTooltip"
|
||||
defaultMessage="Reserved spaces are built-in and can only be partially modified."
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiIcon style={{ verticalAlign: 'super' }} type={'lock'} />
|
||||
</EuiToolTip>
|
||||
);
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { SpaceValidator } from '../lib';
|
||||
import { SpaceIdentifier } from './space_identifier';
|
||||
|
||||
|
@ -19,6 +19,8 @@ test('renders without crashing', () => {
|
|||
onChange: jest.fn(),
|
||||
validator: new SpaceValidator(),
|
||||
};
|
||||
const wrapper = shallow(<SpaceIdentifier {...props} />);
|
||||
const wrapper = shallowWithIntl(
|
||||
<SpaceIdentifier.WrappedComponent {...props} intl={null as any} />
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
EuiFormRow,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import React, { ChangeEvent, Component, Fragment } from 'react';
|
||||
import { Space } from '../../../../common/model/space';
|
||||
import { SpaceValidator } from '../lib';
|
||||
|
@ -18,13 +19,14 @@ interface Props {
|
|||
editable: boolean;
|
||||
validator: SpaceValidator;
|
||||
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
editing: boolean;
|
||||
}
|
||||
|
||||
export class SpaceIdentifier extends Component<Props, State> {
|
||||
class SpaceIdentifierUI extends Component<Props, State> {
|
||||
|
||||
private textFieldRef: HTMLInputElement | null = null;
|
||||
|
||||
|
@ -36,6 +38,7 @@ export class SpaceIdentifier extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const { intl } = this.props;
|
||||
const {
|
||||
id = ''
|
||||
} = this.props.space;
|
||||
|
@ -53,7 +56,11 @@ export class SpaceIdentifier extends Component<Props, State> {
|
|||
placeholder={
|
||||
this.state.editing || !this.props.editable
|
||||
? undefined
|
||||
: 'The URL identifier is generated from the space name.'
|
||||
: intl.formatMessage({
|
||||
id:
|
||||
'xpack.spaces.management.spaceIdentifier.urlIdentifierGeneratedFromSpaceNameTooltip',
|
||||
defaultMessage: 'The URL identifier is generated from the space name.',
|
||||
})
|
||||
}
|
||||
value={id}
|
||||
onChange={this.onChange}
|
||||
|
@ -67,15 +74,63 @@ export class SpaceIdentifier extends Component<Props, State> {
|
|||
|
||||
public getLabel = () => {
|
||||
if (!this.props.editable) {
|
||||
return (<p>URL identifier</p>);
|
||||
return (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spaceIdentifier.urlIdentifierTitle"
|
||||
defaultMessage="URL identifier"
|
||||
/>
|
||||
</p>);
|
||||
}
|
||||
|
||||
const editLinkText = this.state.editing ? `[stop editing]` : `[edit]`;
|
||||
return (<p>URL identifier <EuiLink onClick={this.onEditClick}>{editLinkText}</EuiLink></p>);
|
||||
const editLinkText = this.state.editing ? (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spaceIdentifier.stopEditingSpaceNameLinkText"
|
||||
defaultMessage="[stop editing]"
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spaceIdentifier.editSpaceLinkText"
|
||||
defaultMessage="[edit]"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spaceIdentifier.urlIdentifierLabel"
|
||||
defaultMessage="URL identifier"
|
||||
/>
|
||||
<EuiLink onClick={this.onEditClick}>{editLinkText}</EuiLink>
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
public getHelpText = () => {
|
||||
return (<p>If the identifier is <strong>engineering</strong>, the Kibana URL is <br /> https://my-kibana.example<strong>/s/engineering/</strong>app/kibana.</p>);
|
||||
return (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spaceIdentifier.kibanaURLForEngineeringIdentifierDescription"
|
||||
defaultMessage="If the identifier is {engineeringIdentifier}, the Kibana URL is{nextLine}
|
||||
{engineeringKibanaUrl}."
|
||||
values={{
|
||||
engineeringIdentifier: (
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spaceIdentifier.engineeringText"
|
||||
defaultMessage="engineering"
|
||||
/>
|
||||
</strong>
|
||||
),
|
||||
nextLine: <br />,
|
||||
engineeringKibanaUrl: (
|
||||
<React.Fragment>
|
||||
https://my-kibana.example<strong>/s/engineering/</strong>app/kibana
|
||||
</React.Fragment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
public onEditClick = () => {
|
||||
|
@ -93,3 +148,5 @@ export class SpaceIdentifier extends Component<Props, State> {
|
|||
this.props.onChange(e);
|
||||
};
|
||||
}
|
||||
|
||||
export const SpaceIdentifier = injectI18n(SpaceIdentifierUI);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isReservedSpace } from '../../../../common/is_reserved_space';
|
||||
import { Space } from '../../../../common/model/space';
|
||||
import { isValidSpaceIdentifier } from './space_identifier_utils';
|
||||
|
@ -32,11 +33,19 @@ export class SpaceValidator {
|
|||
}
|
||||
|
||||
if (!space.name || !space.name.trim()) {
|
||||
return invalid(`Name is required`);
|
||||
return invalid(
|
||||
i18n.translate('xpack.spaces.management.validateSpace.requiredNameErrorMessage', {
|
||||
defaultMessage: 'Name is required',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (space.name.length > 1024) {
|
||||
return invalid(`Name must not exceed 1024 characters`);
|
||||
return invalid(
|
||||
i18n.translate('xpack.spaces.management.validateSpace.nameMaxLengthErrorMessage', {
|
||||
defaultMessage: 'Name must not exceed 1024 characters',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return valid();
|
||||
|
@ -48,7 +57,11 @@ export class SpaceValidator {
|
|||
}
|
||||
|
||||
if (space.description && space.description.length > 2000) {
|
||||
return invalid(`Description must not exceed 2000 characters`);
|
||||
return invalid(
|
||||
i18n.translate('xpack.spaces.management.validateSpace.describeMaxLengthErrorMessage', {
|
||||
defaultMessage: 'Description must not exceed 2000 characters',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return valid();
|
||||
|
@ -64,11 +77,23 @@ export class SpaceValidator {
|
|||
}
|
||||
|
||||
if (!space.id) {
|
||||
return invalid(`URL identifier is required`);
|
||||
return invalid(
|
||||
i18n.translate('xpack.spaces.management.validateSpace.urlIdentifierRequiredErrorMessage', {
|
||||
defaultMessage: 'URL identifier is required',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (!isValidSpaceIdentifier(space.id)) {
|
||||
return invalid('URL identifier can only contain a-z, 0-9, and the characters "_" and "-"');
|
||||
return invalid(
|
||||
i18n.translate(
|
||||
'xpack.spaces.management.validateSpace.urlIdentifierAllowedCharactersErrorMessage',
|
||||
{
|
||||
defaultMessage:
|
||||
'URL identifier can only contain a-z, 0-9, and the characters "_" and "-"',
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return valid();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
|
||||
// @ts-ignore
|
||||
import template from 'plugins/spaces/views/management/template.html';
|
||||
|
@ -39,11 +40,13 @@ routes.when('/management/spaces/list', {
|
|||
const spacesManager = new SpacesManager($http, chrome, spaceSelectorURL);
|
||||
|
||||
render(
|
||||
<SpacesGridPage
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={userProfile}
|
||||
/>,
|
||||
<I18nProvider>
|
||||
<SpacesGridPage
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={userProfile}
|
||||
/>
|
||||
</I18nProvider>,
|
||||
domNode
|
||||
);
|
||||
|
||||
|
@ -75,11 +78,13 @@ routes.when('/management/spaces/create', {
|
|||
const spacesManager = new SpacesManager($http, chrome, spaceSelectorURL);
|
||||
|
||||
render(
|
||||
<ManageSpacePage
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={userProfile}
|
||||
/>,
|
||||
<I18nProvider>
|
||||
<ManageSpacePage
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={userProfile}
|
||||
/>
|
||||
</I18nProvider>,
|
||||
domNode
|
||||
);
|
||||
|
||||
|
@ -118,12 +123,14 @@ routes.when('/management/spaces/edit/:spaceId', {
|
|||
const spacesManager = new SpacesManager($http, chrome, spaceSelectorURL);
|
||||
|
||||
render(
|
||||
<ManageSpacePage
|
||||
spaceId={spaceId}
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={userProfile}
|
||||
/>,
|
||||
<I18nProvider>
|
||||
<ManageSpacePage
|
||||
spaceId={spaceId}
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={userProfile}
|
||||
/>
|
||||
</I18nProvider>,
|
||||
domNode
|
||||
);
|
||||
|
||||
|
|
|
@ -31,7 +31,11 @@ exports[`SpacesGridPage renders as expected 1`] = `
|
|||
size="m"
|
||||
>
|
||||
<h1>
|
||||
Spaces
|
||||
<FormattedMessage
|
||||
defaultMessage="Spaces"
|
||||
id="xpack.spaces.management.spacesGridPage.spacesTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
@ -46,7 +50,11 @@ exports[`SpacesGridPage renders as expected 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Create space
|
||||
<FormattedMessage
|
||||
defaultMessage="Create space"
|
||||
id="xpack.spaces.management.spacesGridPage.createSpaceButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
@ -107,7 +115,13 @@ exports[`SpacesGridPage renders as expected 1`] = `
|
|||
itemId="id"
|
||||
items={Array []}
|
||||
loading={true}
|
||||
message="loading..."
|
||||
message={
|
||||
<FormattedMessage
|
||||
defaultMessage="loading…"
|
||||
id="xpack.spaces.management.spacesGridPage.loadingTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
pagination={true}
|
||||
responsive={true}
|
||||
search={
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
EuiSpacer,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
// @ts-ignore
|
||||
import { toastNotifications } from 'ui/notify';
|
||||
|
||||
|
@ -36,6 +37,7 @@ interface Props {
|
|||
spacesManager: SpacesManager;
|
||||
spacesNavState: SpacesNavState;
|
||||
userProfile: UserProfile;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -46,7 +48,7 @@ interface State {
|
|||
error: Error | null;
|
||||
}
|
||||
|
||||
export class SpacesGridPage extends Component<Props, State> {
|
||||
class SpacesGridPageUI extends Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
@ -75,6 +77,7 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public getPageContent() {
|
||||
const { intl } = this.props;
|
||||
if (!this.props.userProfile.hasCapability('manageSpaces')) {
|
||||
return <UnauthorizedPrompt />;
|
||||
}
|
||||
|
@ -84,7 +87,12 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
<EuiFlexGroup justifyContent={'spaceBetween'}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText>
|
||||
<h1>Spaces</h1>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spacesGridPage.spacesTitle"
|
||||
defaultMessage="Spaces"
|
||||
/>
|
||||
</h1>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>{this.getPrimaryActionButton()}</EuiFlexItem>
|
||||
|
@ -99,11 +107,23 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
pagination={true}
|
||||
search={{
|
||||
box: {
|
||||
placeholder: 'Search',
|
||||
placeholder: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.searchPlaceholder',
|
||||
defaultMessage: 'Search',
|
||||
}),
|
||||
},
|
||||
}}
|
||||
loading={this.state.loading}
|
||||
message={this.state.loading ? 'loading...' : undefined}
|
||||
message={
|
||||
this.state.loading ? (
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spacesGridPage.loadingTitle"
|
||||
defaultMessage="loading…"
|
||||
/>
|
||||
) : (
|
||||
undefined
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
|
@ -117,7 +137,10 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
window.location.hash = `#/management/spaces/create`;
|
||||
}}
|
||||
>
|
||||
Create space
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.management.spacesGridPage.createSpaceButtonLabel"
|
||||
defaultMessage="Create space"
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
}
|
||||
|
@ -145,6 +168,7 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
};
|
||||
|
||||
public deleteSpace = async () => {
|
||||
const { intl } = this.props;
|
||||
const { spacesManager, spacesNavState } = this.props;
|
||||
|
||||
const space = this.state.selectedSpace;
|
||||
|
@ -158,7 +182,17 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
} catch (error) {
|
||||
const { message: errorMessage = '' } = error.data || {};
|
||||
|
||||
toastNotifications.addDanger(`Error deleting space: ${errorMessage}`);
|
||||
toastNotifications.addDanger(
|
||||
intl.formatMessage(
|
||||
{
|
||||
id: 'xpack.spaces.management.spacesGridPage.errorDeletingSpaceErrorMessage',
|
||||
defaultMessage: 'Error deleting space: {errorMessage}',
|
||||
},
|
||||
{
|
||||
errorMessage,
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
@ -167,7 +201,15 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
|
||||
this.loadGrid();
|
||||
|
||||
const message = `Deleted "${space.name}" space.`;
|
||||
const message = intl.formatMessage(
|
||||
{
|
||||
id: 'xpack.spaces.management.spacesGridPage.spaceSuccessfullyDeletedNotificationMessage',
|
||||
defaultMessage: 'Deleted "{spaceName}" space.',
|
||||
},
|
||||
{
|
||||
spaceName: space.name,
|
||||
}
|
||||
);
|
||||
|
||||
toastNotifications.addSuccess(message);
|
||||
|
||||
|
@ -203,6 +245,7 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
};
|
||||
|
||||
public getColumnConfig() {
|
||||
const { intl } = this.props;
|
||||
return [
|
||||
{
|
||||
field: 'name',
|
||||
|
@ -223,7 +266,10 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
},
|
||||
{
|
||||
field: 'name',
|
||||
name: 'Space',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.spaceColumnName',
|
||||
defaultMessage: 'Space',
|
||||
}),
|
||||
sortable: true,
|
||||
render: (value: string, record: Space) => {
|
||||
return (
|
||||
|
@ -239,20 +285,35 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
},
|
||||
{
|
||||
field: 'id',
|
||||
name: 'Identifier',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.identifierColumnName',
|
||||
defaultMessage: 'Identifier',
|
||||
}),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
name: 'Description',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.descriptionColumnName',
|
||||
defaultMessage: 'Description',
|
||||
}),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: 'Actions',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.actionsColumnName',
|
||||
defaultMessage: 'Actions',
|
||||
}),
|
||||
actions: [
|
||||
{
|
||||
name: 'Edit',
|
||||
description: 'Edit this space.',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.editSpaceActionName',
|
||||
defaultMessage: 'Edit',
|
||||
}),
|
||||
description: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.editSpaceActionDescription',
|
||||
defaultMessage: 'Edit this space.',
|
||||
}),
|
||||
onClick: this.onEditSpaceClick,
|
||||
type: 'icon',
|
||||
icon: 'pencil',
|
||||
|
@ -260,8 +321,14 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
},
|
||||
{
|
||||
available: (record: Space) => !isReservedSpace(record),
|
||||
name: 'Delete',
|
||||
description: 'Delete this space.',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.deleteActionName',
|
||||
defaultMessage: 'Delete',
|
||||
}),
|
||||
description: intl.formatMessage({
|
||||
id: 'xpack.spaces.management.spacesGridPage.deleteThisSpaceActionDescription',
|
||||
defaultMessage: 'Delete this space.',
|
||||
}),
|
||||
onClick: this.onDeleteSpaceClick,
|
||||
type: 'icon',
|
||||
icon: 'trash',
|
||||
|
@ -283,3 +350,5 @@ export class SpacesGridPage extends Component<Props, State> {
|
|||
});
|
||||
};
|
||||
}
|
||||
|
||||
export const SpacesGridPage = injectI18n(SpacesGridPageUI);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* 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 { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { UserProfileProvider } from '../../../../../xpack_main/public/services/user_profile';
|
||||
import { SpaceAvatar } from '../../../components';
|
||||
import { SpacesManager } from '../../../lib';
|
||||
|
@ -54,22 +54,24 @@ const spacesManager = new SpacesManager(mockHttp, mockChrome, '');
|
|||
describe('SpacesGridPage', () => {
|
||||
it('renders as expected', () => {
|
||||
expect(
|
||||
shallow(
|
||||
<SpacesGridPage
|
||||
shallowWithIntl(
|
||||
<SpacesGridPage.WrappedComponent
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={buildUserProfile(true)}
|
||||
intl={null as any}
|
||||
/>
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders the list of spaces', async () => {
|
||||
const wrapper = mount(
|
||||
<SpacesGridPage
|
||||
const wrapper = mountWithIntl(
|
||||
<SpacesGridPage.WrappedComponent
|
||||
spacesManager={spacesManager}
|
||||
spacesNavState={spacesNavState}
|
||||
userProfile={buildUserProfile(true)}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiContextMenuItem, EuiContextMenuPanel, EuiFieldSearch, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import React, { Component } from 'react';
|
||||
import { UserProfile } from '../../../../../xpack_main/public/services/user_profile';
|
||||
import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../../../common/constants';
|
||||
|
@ -16,6 +17,7 @@ interface Props {
|
|||
onSelectSpace: (space: Space) => void;
|
||||
onManageSpacesClick: () => void;
|
||||
userProfile: UserProfile;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -23,20 +25,24 @@ interface State {
|
|||
allowSpacesListFocus: boolean;
|
||||
}
|
||||
|
||||
export class SpacesMenu extends Component<Props, State> {
|
||||
class SpacesMenuUI extends Component<Props, State> {
|
||||
public state = {
|
||||
searchTerm: '',
|
||||
allowSpacesListFocus: false,
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { intl } = this.props;
|
||||
const { searchTerm } = this.state;
|
||||
|
||||
const items = this.getVisibleSpaces(searchTerm).map(this.renderSpaceMenuItem);
|
||||
|
||||
const panelProps = {
|
||||
className: 'spcMenu',
|
||||
title: 'Change current space',
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.spaces.navControl.spacesMenu.changeCurrentSpaceTitle',
|
||||
defaultMessage: 'Change current space',
|
||||
}),
|
||||
watchedItemProps: ['data-search-term'],
|
||||
};
|
||||
|
||||
|
@ -76,8 +82,10 @@ export class SpacesMenu extends Component<Props, State> {
|
|||
if (items.length === 0) {
|
||||
return (
|
||||
<EuiText color="subdued" className="eui-textCenter">
|
||||
{' '}
|
||||
no spaces found{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.navControl.spacesMenu.noSpacesFoundTitle"
|
||||
defaultMessage=" no spaces found "
|
||||
/>
|
||||
</EuiText>
|
||||
);
|
||||
}
|
||||
|
@ -95,10 +103,14 @@ export class SpacesMenu extends Component<Props, State> {
|
|||
};
|
||||
|
||||
private renderSearchField = () => {
|
||||
const { intl } = this.props;
|
||||
return (
|
||||
<div key="manageSpacesSearchField" className="spcMenu__searchFieldWrapper">
|
||||
<EuiFieldSearch
|
||||
placeholder="Find a space"
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.spaces.navControl.spacesMenu.findSpacePlaceholder',
|
||||
defaultMessage: 'Find a space',
|
||||
})}
|
||||
incremental={true}
|
||||
// FIXME needs updated typedef
|
||||
// @ts-ignore
|
||||
|
@ -165,3 +177,5 @@ export class SpacesMenu extends Component<Props, State> {
|
|||
);
|
||||
};
|
||||
}
|
||||
|
||||
export const SpacesMenu = injectI18n(SpacesMenuUI);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiAvatar, EuiPopover, PopoverAnchorPosition } from '@elastic/eui';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import React, { Component, ComponentClass } from 'react';
|
||||
import { UserProfile } from '../../../../xpack_main/public/services/user_profile';
|
||||
import { Space } from '../../../common/model/space';
|
||||
|
@ -70,12 +71,14 @@ export class NavControlPopover extends Component<Props, State> {
|
|||
);
|
||||
} else {
|
||||
element = (
|
||||
<SpacesMenu
|
||||
spaces={this.state.spaces}
|
||||
onSelectSpace={this.onSelectSpace}
|
||||
userProfile={this.props.userProfile}
|
||||
onManageSpacesClick={this.toggleSpaceSelector}
|
||||
/>
|
||||
<I18nProvider>
|
||||
<SpacesMenu
|
||||
spaces={this.state.spaces}
|
||||
onSelectSpace={this.onSelectSpace}
|
||||
userProfile={this.props.userProfile}
|
||||
onManageSpacesClick={this.toggleSpaceSelector}
|
||||
/>
|
||||
</I18nProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,11 @@ exports[`it renders without crashing 1`] = `
|
|||
textTransform="none"
|
||||
>
|
||||
<h1>
|
||||
Select your space
|
||||
<FormattedMessage
|
||||
defaultMessage="Select your space"
|
||||
id="xpack.spaces.spaceSelector.selectSpacesTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<EuiText
|
||||
|
@ -38,7 +42,11 @@ exports[`it renders without crashing 1`] = `
|
|||
size="s"
|
||||
>
|
||||
<p>
|
||||
You can change your space at anytime
|
||||
<FormattedMessage
|
||||
defaultMessage="You can change your space at anytime"
|
||||
id="xpack.spaces.spaceSelector.changeSpaceAnytimeAvailabilityText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiPageHeader>
|
||||
|
@ -72,7 +80,11 @@ exports[`it renders without crashing 1`] = `
|
|||
size="m"
|
||||
textAlign="center"
|
||||
>
|
||||
No spaces match search criteria
|
||||
<FormattedMessage
|
||||
defaultMessage="No spaces match search criteria"
|
||||
id="xpack.spaces.spaceSelector.noSpacesMatchSearchCriteriaDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiText>
|
||||
</React.Fragment>
|
||||
</EuiPageContent>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import { SpacesManager } from 'plugins/spaces/lib/spaces_manager';
|
||||
// @ts-ignore
|
||||
import template from 'plugins/spaces/views/space_selector/space_selector.html';
|
||||
|
@ -26,7 +27,12 @@ module.controller(
|
|||
|
||||
const spacesManager = new SpacesManager($http, chrome, spaceSelectorURL);
|
||||
|
||||
render(<SpaceSelector spaces={spaces} spacesManager={spacesManager} />, domNode);
|
||||
render(
|
||||
<I18nProvider>
|
||||
<SpaceSelector spaces={spaces} spacesManager={spacesManager} />
|
||||
</I18nProvider>,
|
||||
domNode
|
||||
);
|
||||
|
||||
// unmount react on controller destroy
|
||||
$scope.$on('$destroy', () => {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { render, shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { renderWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import chrome from 'ui/chrome';
|
||||
import { Space } from '../../../common/model/space';
|
||||
import { SpacesManager } from '../../lib/spaces_manager';
|
||||
|
@ -31,7 +31,13 @@ function getSpacesManager(spaces: Space[] = []) {
|
|||
|
||||
test('it renders without crashing', () => {
|
||||
const spacesManager = getSpacesManager();
|
||||
const component = shallow(<SpaceSelector spaces={[]} spacesManager={spacesManager as any} />);
|
||||
const component = shallowWithIntl(
|
||||
<SpaceSelector.WrappedComponent
|
||||
spaces={[]}
|
||||
spacesManager={spacesManager as any}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
@ -46,7 +52,13 @@ test('it uses the spaces on props, when provided', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const component = render(<SpaceSelector spaces={spaces} spacesManager={spacesManager as any} />);
|
||||
const component = renderWithIntl(
|
||||
<SpaceSelector.WrappedComponent
|
||||
spaces={spaces}
|
||||
spacesManager={spacesManager as any}
|
||||
intl={null as any}
|
||||
/>
|
||||
);
|
||||
|
||||
return Promise.resolve().then(() => {
|
||||
expect(component.find('.spaceCard')).toHaveLength(1);
|
||||
|
@ -65,7 +77,9 @@ test('it queries for spaces when not provided on props', () => {
|
|||
|
||||
const spacesManager = getSpacesManager(spaces);
|
||||
|
||||
shallow(<SpaceSelector spacesManager={spacesManager as any} />);
|
||||
shallowWithIntl(
|
||||
<SpaceSelector.WrappedComponent spacesManager={spacesManager as any} intl={null as any} />
|
||||
);
|
||||
|
||||
return Promise.resolve().then(() => {
|
||||
expect(spacesManager.getSpaces).toHaveBeenCalledTimes(1);
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import { SpacesManager } from 'plugins/spaces/lib';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../../common/constants';
|
||||
|
@ -26,6 +27,7 @@ import { SpaceCards } from '../components/space_cards';
|
|||
interface Props {
|
||||
spaces?: Space[];
|
||||
spacesManager: SpacesManager;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -34,7 +36,7 @@ interface State {
|
|||
spaces: Space[];
|
||||
}
|
||||
|
||||
export class SpaceSelector extends Component<Props, State> {
|
||||
class SpaceSelectorUI extends Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
|
@ -89,11 +91,22 @@ export class SpaceSelector extends Component<Props, State> {
|
|||
<span className="spcSpaceSelector__logo">
|
||||
<EuiIcon size="xxl" type={`logoKibana`} />
|
||||
</span>
|
||||
|
||||
<EuiTitle size="l">
|
||||
<h1>Select your space</h1>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.spaceSelector.selectSpacesTitle"
|
||||
defaultMessage="Select your space"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>You can change your space at anytime</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.spaceSelector.changeSpaceAnytimeAvailabilityText"
|
||||
defaultMessage="You can change your space at anytime"
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiPageHeader>
|
||||
<EuiPageContent className="spcSpaceSelector__pageContent">
|
||||
|
@ -118,7 +131,10 @@ export class SpaceSelector extends Component<Props, State> {
|
|||
// @ts-ignore
|
||||
textAlign="center"
|
||||
>
|
||||
No spaces match search criteria
|
||||
<FormattedMessage
|
||||
id="xpack.spaces.spaceSelector.noSpacesMatchSearchCriteriaDescription"
|
||||
defaultMessage="No spaces match search criteria"
|
||||
/>
|
||||
</EuiText>
|
||||
</Fragment>
|
||||
)}
|
||||
|
@ -129,6 +145,7 @@ export class SpaceSelector extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public getSearchField = () => {
|
||||
const { intl } = this.props;
|
||||
if (!this.props.spaces || this.props.spaces.length < SPACE_SEARCH_COUNT_THRESHOLD) {
|
||||
return null;
|
||||
}
|
||||
|
@ -136,7 +153,10 @@ export class SpaceSelector extends Component<Props, State> {
|
|||
<EuiFlexItem className="spcSpaceSelector__searchHolder">
|
||||
<EuiFieldSearch
|
||||
className="spcSpaceSelector__searchField"
|
||||
placeholder="Find a space"
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.spaces.spaceSelector.findSpacePlaceholder',
|
||||
defaultMessage: 'Find a space',
|
||||
})}
|
||||
incremental={true}
|
||||
// @ts-ignore
|
||||
onSearch={this.onSearch}
|
||||
|
@ -155,3 +175,5 @@ export class SpaceSelector extends Component<Props, State> {
|
|||
this.props.spacesManager.changeSelectedSpace(space);
|
||||
};
|
||||
}
|
||||
|
||||
export const SpaceSelector = injectI18n(SpaceSelectorUI);
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
],
|
||||
"plugins/spaces/*": [
|
||||
"x-pack/plugins/spaces/public/*"
|
||||
],
|
||||
"test_utils/*": [
|
||||
"x-pack/test_utils/*"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue