mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
* EUIfication of Wizard Step 2 * Update snapshot * Remove unnecessarily function bind * Ignor ts untill file is converted to ts * Apply styles * Make button filled * Update labels * Update types * Unfilled button * Update styles * Remove unused translations * Add "manage index patterns" button * Remove buttons and hide per page options; get rid of injectI18n * Add back button * Update header * Remove back button * Update data test subject * Add data-test-subj for tabs * Fix test * Make test subj consistent with initial data test subj * Move SavedObject initializing to render function * Update propTypes
This commit is contained in:
parent
f968ebf8f8
commit
d0c6aebf39
13 changed files with 258 additions and 195 deletions
|
@ -49,7 +49,7 @@ exports[`render 1`] = `
|
|||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<InjectIntl(SavedObjectFinderUI)
|
||||
<SavedObjectFinder
|
||||
callToActionButton={
|
||||
<EuiButton
|
||||
color="primary"
|
||||
|
|
|
@ -26,7 +26,7 @@ exports[`render 1`] = `
|
|||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<InjectIntl(SavedObjectFinderUI)
|
||||
<SavedObjectFinder
|
||||
callToActionButton={
|
||||
<EuiButton
|
||||
color="primary"
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
import './editor/editor';
|
||||
import './wizard/wizard';
|
||||
import 'ui/draggable/draggable_container';
|
||||
import 'ui/draggable/draggable_item';
|
||||
import 'ui/draggable/draggable_handle';
|
||||
|
|
|
@ -150,8 +150,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
|
|||
>
|
||||
<div>
|
||||
<div
|
||||
class="euiModal visNewVisDialog"
|
||||
style="max-width: 100vw;"
|
||||
class="euiModal euiModal--maxWidth-default visNewVisDialog"
|
||||
tabindex="0"
|
||||
>
|
||||
<button
|
||||
|
@ -361,7 +360,7 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
|
|||
>
|
||||
<EuiModal
|
||||
className="visNewVisDialog"
|
||||
maxWidth="100vw"
|
||||
maxWidth={true}
|
||||
onClose={[Function]}
|
||||
>
|
||||
<FocusTrap
|
||||
|
@ -378,13 +377,8 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
|
|||
>
|
||||
<div>
|
||||
<div
|
||||
className="euiModal visNewVisDialog"
|
||||
className="euiModal euiModal--maxWidth-default visNewVisDialog"
|
||||
onKeyDown={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "100vw",
|
||||
}
|
||||
}
|
||||
tabIndex={0}
|
||||
>
|
||||
<EuiI18n
|
||||
|
@ -1096,8 +1090,7 @@ exports[`NewVisModal should render as expected 1`] = `
|
|||
>
|
||||
<div>
|
||||
<div
|
||||
class="euiModal visNewVisDialog"
|
||||
style="max-width: 100vw;"
|
||||
class="euiModal euiModal--maxWidth-default visNewVisDialog"
|
||||
tabindex="0"
|
||||
>
|
||||
<button
|
||||
|
@ -1304,7 +1297,7 @@ exports[`NewVisModal should render as expected 1`] = `
|
|||
>
|
||||
<EuiModal
|
||||
className="visNewVisDialog"
|
||||
maxWidth="100vw"
|
||||
maxWidth={true}
|
||||
onClose={[Function]}
|
||||
>
|
||||
<FocusTrap
|
||||
|
@ -1321,13 +1314,8 @@ exports[`NewVisModal should render as expected 1`] = `
|
|||
>
|
||||
<div>
|
||||
<div
|
||||
className="euiModal visNewVisDialog"
|
||||
className="euiModal euiModal--maxWidth-default visNewVisDialog"
|
||||
onKeyDown={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"maxWidth": "100vw",
|
||||
}
|
||||
}
|
||||
tabIndex={0}
|
||||
>
|
||||
<EuiI18n
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
.visNewVisDialog {
|
||||
max-width: 100vw;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='166' height='157' viewBox='0 0 166 157'%3E%3Cdefs%3E%3ClinearGradient id='untitled-2-a' x1='0%25' y1='0%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%23FFF' stop-opacity='.2'/%3E%3Cstop offset='100%25' stop-opacity='0'/%3E%3C/linearGradient%3E%3CradialGradient id='untitled-2-b' cx='0%25' cy='0%25' r='127.787%25' fx='0%25' fy='0%25' gradientTransform='matrix(.681 .68098 -.63326 .7323 0 0)'%3E%3Cstop offset='0%25' stop-color='%23BBB' stop-opacity='.1'/%3E%3Cstop offset='100%25' stop-opacity='.5'/%3E%3C/radialGradient%3E%3ClinearGradient id='untitled-2-c' x1='0%25' y1='0%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%23FFF' stop-opacity='.4'/%3E%3Cstop offset='100%25' stop-opacity='0'/%3E%3C/linearGradient%3E%3CradialGradient id='untitled-2-d' cx='0%25' cy='0%25' r='148.851%25' fx='0%25' fy='0%25' gradientTransform='matrix(.6718 .67182 -.74072 .60932 0 0)'%3E%3Cstop offset='0%25' stop-color='%23FFF' stop-opacity='.101'/%3E%3Cstop offset='100%25' stop-opacity='.15'/%3E%3C/radialGradient%3E%3CradialGradient id='untitled-2-e' cx='0%25' cy='0%25' r='127.349%25' fx='0%25' fy='0%25' gradientTransform='matrix(.68331 .68332 -.73013 .63951 0 0)'%3E%3Cstop offset='0%25' stop-color='%23BBB' stop-opacity='.1'/%3E%3Cstop offset='100%25' stop-opacity='.5'/%3E%3C/radialGradient%3E%3C/defs%3E%3Cg opacity='.5' fill='none' fill-rule='evenodd' transform='matrix(-1 0 0 1 166 0)'%3E%3Cg opacity='.65' transform='matrix(0 -1 -1 0 146 157)'%3E%3Cpolygon fill='%23DD0A73' points='0 0 157 146 0 146' opacity='.418'/%3E%3Cpolygon fill='url(%23untitled-2-a)' points='0 0 157 146 0 146' style='mix-blend-mode:overlay'/%3E%3Cpolygon fill='url(%23untitled-2-b)' points='0 0 157 146 0 146' opacity='.618' style='mix-blend-mode:overlay'/%3E%3C/g%3E%3Cg opacity='.65' transform='translate(88 71)'%3E%3Cpath fill='%23017F75' d='M0,86 L78,86 C74.2038079,48.730962 43.6293886,16.7871605 0,0 L0,86 Z' opacity='.409'/%3E%3Cpath fill='url(%23untitled-2-c)' d='M0,86 L78,86 C74.2038079,48.730962 43.6293886,16.7871605 0,0 L0,86 Z' style='mix-blend-mode:overlay'/%3E%3Cpath fill='url(%23untitled-2-d)' d='M0,86 L78,86 C74.2038079,48.730962 43.6293886,16.7871605 0,0 L0,86 Z' opacity='.663' style='mix-blend-mode:overlay'/%3E%3C/g%3E%3Cg opacity='.15' transform='translate(73 79)'%3E%3Cpolygon fill='%23353535' points='0 0 73 78 0 78' opacity='.38'/%3E%3Cpolygon fill='url(%23untitled-2-a)' points='0 0 73 78 0 78' style='mix-blend-mode:overlay'/%3E%3Cpolygon fill='url(%23untitled-2-e)' points='0 0 73 78 0 78' style='mix-blend-mode:overlay'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A");
|
||||
background-repeat: no-repeat;
|
||||
background-position: calc(100% + 1px) calc(100% + 1px);
|
||||
background-size: 37%;
|
||||
}
|
||||
|
||||
.visNewVisSearchDialog {
|
||||
min-height: $euiSizeL * 20;
|
||||
}
|
||||
|
||||
.visNewVisDialog__body {
|
||||
display: flex;
|
||||
padding: $euiSizeM $euiSizeL 0;
|
||||
|
|
|
@ -23,6 +23,7 @@ import { EuiModal, EuiOverlayMask } from '@elastic/eui';
|
|||
|
||||
import { VisualizeConstants } from '../visualize_constants';
|
||||
|
||||
import { SearchSelection } from './search_selection';
|
||||
import { TypeSelection } from './type_selection';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
|
@ -35,7 +36,14 @@ interface TypeSelectionProps {
|
|||
editorParams?: string[];
|
||||
}
|
||||
|
||||
class NewVisModal extends React.Component<TypeSelectionProps> {
|
||||
interface TypeSelectionState {
|
||||
showSearchVisModal: boolean;
|
||||
visType?: VisType;
|
||||
}
|
||||
|
||||
const baseUrl = `#${VisualizeConstants.CREATE_PATH}?`;
|
||||
|
||||
class NewVisModal extends React.Component<TypeSelectionProps, TypeSelectionState> {
|
||||
public static defaultProps = {
|
||||
editorParams: [],
|
||||
};
|
||||
|
@ -45,6 +53,10 @@ class NewVisModal extends React.Component<TypeSelectionProps> {
|
|||
constructor(props: TypeSelectionProps) {
|
||||
super(props);
|
||||
this.isLabsEnabled = chrome.getUiSettingsClient().get('visualize:enableLabs');
|
||||
|
||||
this.state = {
|
||||
showSearchVisModal: false,
|
||||
};
|
||||
}
|
||||
|
||||
public render() {
|
||||
|
@ -52,26 +64,50 @@ class NewVisModal extends React.Component<TypeSelectionProps> {
|
|||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiOverlayMask>
|
||||
<EuiModal onClose={this.props.onClose} maxWidth={'100vw'} className="visNewVisDialog">
|
||||
const selectionModal =
|
||||
this.state.showSearchVisModal && this.state.visType ? (
|
||||
<EuiModal onClose={this.onCloseModal} className="visNewVisSearchDialog">
|
||||
<SearchSelection onSearchSelected={this.onSearchSelected} visType={this.state.visType} />
|
||||
</EuiModal>
|
||||
) : (
|
||||
<EuiModal onClose={this.onCloseModal} className="visNewVisDialog">
|
||||
<TypeSelection
|
||||
showExperimental={this.isLabsEnabled}
|
||||
onVisTypeSelected={this.onVisTypeSelected}
|
||||
visTypesRegistry={this.props.visTypesRegistry}
|
||||
/>
|
||||
</EuiModal>
|
||||
</EuiOverlayMask>
|
||||
);
|
||||
);
|
||||
|
||||
return <EuiOverlayMask>{selectionModal}</EuiOverlayMask>;
|
||||
}
|
||||
|
||||
private onVisTypeSelected = (visType: VisType) => {
|
||||
const baseUrl =
|
||||
visType.requiresSearch && visType.options.showIndexSelection
|
||||
? `#${VisualizeConstants.WIZARD_STEP_2_PAGE_PATH}?`
|
||||
: `#${VisualizeConstants.CREATE_PATH}?`;
|
||||
const params = [`type=${encodeURIComponent(visType.name)}`, ...this.props.editorParams!];
|
||||
private onCloseModal = () => {
|
||||
this.setState({ showSearchVisModal: false });
|
||||
this.props.onClose();
|
||||
};
|
||||
|
||||
private onVisTypeSelected = (visType: VisType) => {
|
||||
if (visType.requiresSearch && visType.options.showIndexSelection) {
|
||||
this.setState({
|
||||
showSearchVisModal: true,
|
||||
visType,
|
||||
});
|
||||
} else {
|
||||
const params = [`type=${encodeURIComponent(visType.name)}`, ...this.props.editorParams!];
|
||||
this.props.onClose();
|
||||
location.assign(`${baseUrl}${params.join('&')}`);
|
||||
}
|
||||
};
|
||||
|
||||
private onSearchSelected = (searchId: string, searchType: string) => {
|
||||
this.props.onClose();
|
||||
|
||||
const params = [
|
||||
`type=${encodeURIComponent(this.state.visType!.name)}`,
|
||||
`${searchType === 'search' ? 'savedSearchId' : 'indexPattern'}=${searchId}`,
|
||||
...this.props.editorParams!,
|
||||
];
|
||||
location.assign(`${baseUrl}${params.join('&')}`);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
export { SearchSelection } from './search_selection';
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiModalBody,
|
||||
EuiModalHeader,
|
||||
EuiModalHeaderTitle,
|
||||
EuiSpacer,
|
||||
EuiTab,
|
||||
EuiTabs,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
|
||||
import { VisType } from 'ui/vis';
|
||||
|
||||
import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder';
|
||||
|
||||
interface SearchSelectionProps {
|
||||
onSearchSelected: (searchId: string, searchType: string) => void;
|
||||
visType: VisType;
|
||||
}
|
||||
|
||||
interface SearchSelectionState {
|
||||
selectedTabId: string;
|
||||
}
|
||||
|
||||
interface TabProps {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const INDEX_PATTERNS_TAB_ID = 'indexPatterns';
|
||||
const SAVED_SEARCHES_TAB_ID = 'savedSearches';
|
||||
|
||||
export class SearchSelection extends React.Component<SearchSelectionProps, SearchSelectionState> {
|
||||
public state = {
|
||||
selectedTabId: INDEX_PATTERNS_TAB_ID,
|
||||
};
|
||||
private fixedPageSize: number = 8;
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<EuiModalHeader>
|
||||
<EuiModalHeaderTitle>
|
||||
<FormattedMessage
|
||||
id="kbn.visualize.newVisWizard.newVisTypeTitle"
|
||||
defaultMessage="New {visTypeName}"
|
||||
values={{ visTypeName: this.props.visType.title }}
|
||||
/>{' '}
|
||||
/{' '}
|
||||
<FormattedMessage
|
||||
id="kbn.visualize.newVisWizard.chooseSourceTitle"
|
||||
defaultMessage="Choose a source"
|
||||
/>
|
||||
</EuiModalHeaderTitle>
|
||||
</EuiModalHeader>
|
||||
<EuiModalBody>
|
||||
<EuiTabs size="m">{this.renderTabs()}</EuiTabs>
|
||||
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
{this.renderTab()}
|
||||
</EuiModalBody>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
private onSelectedTabChanged = (tab: TabProps) => {
|
||||
this.setState({
|
||||
selectedTabId: tab.id,
|
||||
});
|
||||
};
|
||||
|
||||
private renderTabs() {
|
||||
const tabs = [
|
||||
{
|
||||
id: INDEX_PATTERNS_TAB_ID,
|
||||
name: i18n.translate('kbn.visualize.newVisWizard.indexPatternTabLabel', {
|
||||
defaultMessage: 'Index pattern',
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: SAVED_SEARCHES_TAB_ID,
|
||||
name: i18n.translate('kbn.visualize.newVisWizard.savedSearchTabLabel', {
|
||||
defaultMessage: 'Saved search',
|
||||
}),
|
||||
},
|
||||
];
|
||||
const { selectedTabId } = this.state;
|
||||
|
||||
return tabs.map(tab => (
|
||||
<EuiTab
|
||||
onClick={() => this.onSelectedTabChanged(tab)}
|
||||
isSelected={tab.id === selectedTabId}
|
||||
key={tab.id}
|
||||
data-test-subj={`${tab.id}Tab`}
|
||||
>
|
||||
{tab.name}
|
||||
</EuiTab>
|
||||
));
|
||||
}
|
||||
|
||||
private renderTab() {
|
||||
if (this.state.selectedTabId === SAVED_SEARCHES_TAB_ID) {
|
||||
return (
|
||||
<SavedObjectFinder
|
||||
key="searchSavedObjectFinder"
|
||||
onChoose={this.props.onSearchSelected}
|
||||
noItemsMessage={i18n.translate(
|
||||
'kbn.visualize.newVisWizard.savedSearchTab.notFoundLabel',
|
||||
{ defaultMessage: 'No matching saved searches found.' }
|
||||
)}
|
||||
savedObjectType="search"
|
||||
fixedPageSize={this.fixedPageSize}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SavedObjectFinder
|
||||
key="visSavedObjectFinder"
|
||||
onChoose={this.props.onSearchSelected}
|
||||
noItemsMessage={i18n.translate('kbn.visualize.newVisWizard.indexPatternTab.notFoundLabel', {
|
||||
defaultMessage: 'No matching index patterns found.',
|
||||
})}
|
||||
savedObjectType="index-pattern"
|
||||
fixedPageSize={this.fixedPageSize}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
<div class="kuiViewContent kuiViewContent--constrainedWidth kuiViewContentItem" data-test-subj="visualizeSelectSearch">
|
||||
<div class="visWizard kuiViewContentItem">
|
||||
<div class="visWizard__column visWizard__column--small">
|
||||
<h2
|
||||
class="kuiTitle kuiVerticalRhythm"
|
||||
i18n-id="kbn.visualize.newVisWizard.createFromNewSearchTitle"
|
||||
i18n-default-message="From a New Search, Select Index"
|
||||
></h2>
|
||||
|
||||
<paginated-selectable-list
|
||||
per-page="20"
|
||||
list="indexPattern.list"
|
||||
list-property="attributes.title"
|
||||
user-make-url="makeUrl"
|
||||
class="visWizard__row visWizard__list--paginated--selectable kuiVerticalRhythm"
|
||||
disable-auto-focus="true"
|
||||
></paginated-selectable-list>
|
||||
</div>
|
||||
|
||||
<div class="visWizard__column visWizard__column--large">
|
||||
<h2
|
||||
class="kuiTitle kuiVerticalRhythm"
|
||||
i18n-id="kbn.visualize.newVisWizard.createFromSavedSearchTitle"
|
||||
i18n-default-message="Or, From a Saved Search"
|
||||
></h2>
|
||||
|
||||
<!-- Saved searches -->
|
||||
<saved-object-finder
|
||||
type="searches"
|
||||
class="visWizard__row visWizard__savedObjectFinder kuiVerticalRhythm"
|
||||
make-url="step2WithSearchUrl"
|
||||
disable-auto-focus="true"
|
||||
></saved-object-finder>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import '../saved_visualizations/saved_visualizations';
|
||||
import 'ui/directives/saved_object_finder';
|
||||
import 'ui/directives/paginated_selectable_list';
|
||||
import '../../discover/saved_searches/saved_searches';
|
||||
|
||||
import { DashboardConstants } from '../../dashboard/dashboard_constants';
|
||||
import { VisualizeConstants } from '../visualize_constants';
|
||||
import routes from 'ui/routes';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import visualizeWizardStep2Template from './step_2.html';
|
||||
import { SavedObjectsClientProvider } from 'ui/saved_objects';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { getWizardStep2Breadcrumbs } from '../breadcrumbs';
|
||||
|
||||
const module = uiModules.get('app/visualize', ['kibana/courier']);
|
||||
|
||||
/********
|
||||
/** Wizard Step 2
|
||||
/********/
|
||||
|
||||
// Redirect old route to new route.
|
||||
// NOTE: Accessing this route directly means the user has entered into the wizard UX without
|
||||
// selecting a Visualization type in step 1. So we want to redirect them to step 1, not step 2.
|
||||
routes.when('/visualize/step/2', {
|
||||
redirectTo: VisualizeConstants.WIZARD_STEP_1_PAGE_PATH,
|
||||
});
|
||||
|
||||
routes.when(VisualizeConstants.WIZARD_STEP_2_PAGE_PATH, {
|
||||
template: visualizeWizardStep2Template,
|
||||
k7Breadcrumbs: getWizardStep2Breadcrumbs,
|
||||
controller: 'VisualizeWizardStep2',
|
||||
resolve: {
|
||||
indexPatterns: function (Private) {
|
||||
const savedObjectsClient = Private(SavedObjectsClientProvider);
|
||||
|
||||
return savedObjectsClient.find({
|
||||
type: 'index-pattern',
|
||||
fields: ['title'],
|
||||
perPage: 10000
|
||||
}).then(response => response.savedObjects);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.controller('VisualizeWizardStep2', function ($route, $scope, kbnUrl) {
|
||||
const type = $route.current.params.type;
|
||||
const addToDashMode = $route.current.params[DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM];
|
||||
kbnUrl.removeParam(DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM);
|
||||
|
||||
$scope.step2WithSearchUrl = function (hit) {
|
||||
if (addToDashMode) {
|
||||
return kbnUrl.eval(
|
||||
`#${VisualizeConstants.CREATE_PATH}` +
|
||||
`?type={{type}}&savedSearchId={{id}}` +
|
||||
`&${DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM}`,
|
||||
{ type: type, id: hit.id }
|
||||
);
|
||||
}
|
||||
|
||||
return kbnUrl.eval(
|
||||
`#${VisualizeConstants.CREATE_PATH}?type={{type}}&savedSearchId={{id}}`,
|
||||
{ type: type, id: hit.id }
|
||||
);
|
||||
};
|
||||
|
||||
timefilter.disableAutoRefreshSelector();
|
||||
timefilter.disableTimeRangeSelector();
|
||||
|
||||
$scope.indexPattern = {
|
||||
selection: null,
|
||||
list: $route.current.locals.indexPatterns
|
||||
};
|
||||
|
||||
$scope.makeUrl = function (pattern) {
|
||||
if (!pattern) return;
|
||||
|
||||
if (addToDashMode) {
|
||||
return `#${VisualizeConstants.CREATE_PATH}` +
|
||||
`?${DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM}` +
|
||||
`&type=${type}&indexPattern=${pattern.id}`;
|
||||
}
|
||||
|
||||
return `#${VisualizeConstants.CREATE_PATH}?type=${type}&indexPattern=${pattern.id}`;
|
||||
};
|
||||
});
|
|
@ -20,7 +20,6 @@
|
|||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { InjectedIntlProps } from 'react-intl';
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
import {
|
||||
|
@ -32,7 +31,7 @@ import {
|
|||
EuiTableCriteria,
|
||||
} from '@elastic/eui';
|
||||
import { Direction } from '@elastic/eui/src/services/sort/sort_direction';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { SavedObjectAttributes } from '../../../../server/saved_objects';
|
||||
import { VisTypesRegistryProvider } from '../../registry/vis_types';
|
||||
|
@ -52,7 +51,7 @@ interface SavedObjectFinderUIState {
|
|||
sortDirection?: Direction;
|
||||
}
|
||||
|
||||
interface SavedObjectFinderUIProps extends InjectedIntlProps {
|
||||
interface BaseSavedObjectFinder {
|
||||
callToActionButton?: React.ReactNode;
|
||||
onChoose?: (
|
||||
id: SavedObject<SavedObjectAttributes>['id'],
|
||||
|
@ -60,23 +59,31 @@ interface SavedObjectFinderUIProps extends InjectedIntlProps {
|
|||
) => void;
|
||||
makeUrl?: (id: SavedObject<SavedObjectAttributes>['id']) => void;
|
||||
noItemsMessage?: React.ReactNode;
|
||||
savedObjectType: 'visualization' | 'search';
|
||||
savedObjectType: 'visualization' | 'search' | 'index-pattern';
|
||||
visTypes?: VisTypesRegistryProvider;
|
||||
initialPageSize?: 5 | 10 | 15;
|
||||
}
|
||||
|
||||
class SavedObjectFinderUI extends React.Component<
|
||||
SavedObjectFinderUIProps,
|
||||
SavedObjectFinderUIState
|
||||
> {
|
||||
interface SavedObjectFinderFixedPage extends BaseSavedObjectFinder {
|
||||
initialPageSize?: undefined;
|
||||
fixedPageSize: number;
|
||||
}
|
||||
|
||||
interface SavedObjectFinderInitialPageSize extends BaseSavedObjectFinder {
|
||||
initialPageSize?: 5 | 10 | 15;
|
||||
fixedPageSize?: undefined;
|
||||
}
|
||||
type SavedObjectFinderProps = SavedObjectFinderFixedPage | SavedObjectFinderInitialPageSize;
|
||||
|
||||
class SavedObjectFinder extends React.Component<SavedObjectFinderProps, SavedObjectFinderUIState> {
|
||||
public static propTypes = {
|
||||
callToActionButton: PropTypes.node,
|
||||
onChoose: PropTypes.func,
|
||||
makeUrl: PropTypes.func,
|
||||
noItemsMessage: PropTypes.node,
|
||||
savedObjectType: PropTypes.oneOf(['visualization', 'search']).isRequired,
|
||||
savedObjectType: PropTypes.oneOf(['visualization', 'search', 'index-pattern']).isRequired,
|
||||
visTypes: PropTypes.object,
|
||||
initialPageSize: PropTypes.number,
|
||||
initialPageSize: PropTypes.oneOf([5, 10, 15]),
|
||||
fixedPageSize: PropTypes.number,
|
||||
};
|
||||
|
||||
private isComponentMounted: boolean = false;
|
||||
|
@ -128,14 +135,14 @@ class SavedObjectFinderUI extends React.Component<
|
|||
}
|
||||
}, 300);
|
||||
|
||||
constructor(props: SavedObjectFinderUIProps) {
|
||||
constructor(props: SavedObjectFinderProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
items: [],
|
||||
isFetchingItems: false,
|
||||
page: 0,
|
||||
perPage: props.initialPageSize || 15,
|
||||
perPage: props.initialPageSize || props.fixedPageSize || 15,
|
||||
filter: '',
|
||||
};
|
||||
}
|
||||
|
@ -225,8 +232,7 @@ class SavedObjectFinderUI extends React.Component<
|
|||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiFieldSearch
|
||||
placeholder={this.props.intl.formatMessage({
|
||||
id: 'common.ui.savedObjects.finder.searchPlaceholder',
|
||||
placeholder={i18n.translate('common.ui.savedObjects.finder.searchPlaceholder', {
|
||||
defaultMessage: 'Search…',
|
||||
})}
|
||||
fullWidth
|
||||
|
@ -255,6 +261,7 @@ class SavedObjectFinderUI extends React.Component<
|
|||
pageIndex: this.state.page,
|
||||
pageSize: this.state.perPage,
|
||||
totalItemCount: this.state.items.length,
|
||||
hidePerPageOptions: Boolean(this.props.fixedPageSize),
|
||||
pageSizeOptions: [5, 10, 15],
|
||||
};
|
||||
// TODO there should be a Type in EUI for that, replace if it exists
|
||||
|
@ -268,8 +275,7 @@ class SavedObjectFinderUI extends React.Component<
|
|||
const tableColumns = [
|
||||
{
|
||||
field: 'title',
|
||||
name: this.props.intl.formatMessage({
|
||||
id: 'common.ui.savedObjects.finder.titleLabel',
|
||||
name: i18n.translate('common.ui.savedObjects.finder.titleLabel', {
|
||||
defaultMessage: 'Title',
|
||||
}),
|
||||
sortable: true,
|
||||
|
@ -313,4 +319,4 @@ class SavedObjectFinderUI extends React.Component<
|
|||
}
|
||||
}
|
||||
|
||||
export const SavedObjectFinder = injectI18n(SavedObjectFinderUI);
|
||||
export { SavedObjectFinder };
|
||||
|
|
|
@ -307,12 +307,13 @@ export function VisualizePageProvider({ getService, getPageObjects }) {
|
|||
}
|
||||
|
||||
async clickNewSearch(indexPattern = this.index.LOGSTASH_TIME_BASED) {
|
||||
await testSubjects.click(`paginatedListItem-${indexPattern}`);
|
||||
await testSubjects.click(`savedObjectTitle${indexPattern.split(' ').join('-')}`);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
|
||||
async clickSavedSearch(savedSearchName) {
|
||||
await find.clickByPartialLinkText(savedSearchName);
|
||||
await testSubjects.click('savedSearchesTab');
|
||||
await testSubjects.click(`savedObjectTitle${savedSearchName.split(' ').join('-')}`);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
|
||||
|
|
|
@ -2064,8 +2064,6 @@
|
|||
"kbn.visualize.listing.listingLimitHelpText": "您有 {totalItems} 个可视化,但“listingLimit”设置使得下表最多只能显示 {listingLimit} 个。此设置可在以下选项下更改:",
|
||||
"kbn.visualize.listing.noVisualizations.createVisualizationButtonLabel": "创建可视化",
|
||||
"kbn.visualize.listing.noVisualizationsText": "看起来您还没有任何可视化。开始创建一些吧!",
|
||||
"kbn.visualize.newVisWizard.createFromNewSearchTitle": "基于“新搜索”,选择“索引”",
|
||||
"kbn.visualize.newVisWizard.createFromSavedSearchTitle": "或者,基于“已保存的搜索”",
|
||||
"kbn.visualize.newVisWizard.experimentalDescription": "这是实验性可视化。与稳定的可视化相比,其设计和实现均不够成熟,可能会随时发生更改。",
|
||||
"kbn.visualize.newVisWizard.experimentalTitle": "实验性",
|
||||
"kbn.visualize.newVisWizard.experimentalTooltip": "这是实验性可视化。",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue