Merge branch 'master' of github.com:elastic/kibana into implement/kbn-dev-client

This commit is contained in:
spalger 2019-09-29 13:07:58 -07:00
commit 3c302a058a
54 changed files with 250 additions and 198 deletions

View file

@ -29,7 +29,7 @@ xpack.code.ui.enabled: true
https://github.com/Microsoft/TypeScript-Node-Starter
----
`https` is recommend for cloning git repositories.
`https` is recommend for cloning most git repositories. To clone a private repository, <<code-repo-management, use SSH>>.
. Click *Import*.
+

View file

@ -6,20 +6,40 @@ Code starts with an overview of your repositories. You can then use the UI to a
image::images/code-repo-management.png[]
[float]
[[add-delete-a-repo]]
==== Add and delete a repo
The <<code-import-first-repo, Import your first repository>> page provides step-by-step instructions for adding a GitHub repo to *Code*. You can fine tune the hostname of the git clone URL in your `kibana.yml` file.
The <<code-import-first-repo, Import your first repository>> page provides step-by-step instructions for adding a GitHub repo to *Code*. You can fine-tune the hostname of the git clone URL in your `kibana.yml` file.
For security reasons, Code allows only a few trusted hostnames, such as github.com, by default. You can add an SSH key to {kib} to clone private repos.
For security reasons, Code allows only a few <<clone-url-management,trusted hostnames>>, such as github.com. To clone private repositories see <<clone-private-repo,add an SSH key>>.
Deleting a repo removes it from local storage and the Elasticsearch index.
To delete a repository, go to the **Repositories** tab, find the name of the repo, and click *Delete*.
[float]
[[clone-private-repo]]
==== Clone private repo with an SSH key
Clones of private repos require an SSH key for authentication. The username associated with your host must have write access to the repository you want to clone.
The following section provides links for generating your ssh key through GitHub. If you already have an SSH key added through your host, skip to step 4.
1. https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key[Generate an ssh key].
2. https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent[Add the ssh key to your ssh-agent.]
3. https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account[Add the ssh key to your host].
4. Copy the ssh key into `data/code/credentials/` under the {kib} folder.
You can now copy private Git repositories into Code.
To delete a repository, find the go to the **Repositories** tab, find the name of the repo and click *Delete*.
[float]
[[reindex-a-repo]]
==== Reindex a repo
*Code* automatically reindexes an imported repo at set intervals, but in some cases you might need to manually refresh the index. For example, you might refresh an index after a new language server is installed. Or, you might want to immediately update the index to the HEAD revision. Click *Reindex* to initiate a reindex.
In some cases you might need to manually refresh the index besides automatic indexing. For example, you might refresh an index after a new language server is installed. Or, you might want to immediately update the index to the HEAD revision. Click *Reindex* to initiate a reindex.
*Code* automatically reindexes an imported repo at set intervals, but in some cases, you might need to refresh the index manually. For example, you might refresh an index after a new language server installs. Or, you might want to update the index to the HEAD revision immediately. Click *Reindex* to initiate a reindex.
[float]
[[clone-url-management]]
==== Clone URL management
For security reasons, *Code* only allows the following hostnames in the git clone URL by default:
@ -46,9 +66,11 @@ xpack.code.security.gitProtocolWhitelist: [ "https" ]
----
[float]
==== Clone repo with SSH key
If your repo clone requires an SSH key for authentication, put the SSH key in `data/code/credentials/` under the {kib} folder.
[[repo-limitations]]
==== Limitations
Consider the following limitations before cloning repositories:
- Only Git is supported. Other version control systems, such as Mercurial and SVN, are not supported.
- Your disk might not have enough space to clone repositories due to {kib} watermark settings. To update your watermark settings, contact your system administrator and request additional disk space.
include::code-install-lang-server.asciidoc[]

View file

@ -19,7 +19,7 @@ With this UI, you can:
[role="screenshot"]
image:management/watcher-ui/images/watches.png["Watcher list"]
{stack-ov}/xpack-alerting.html[Alerting on cluster and index events]
{ref}/xpack-alerting.html[Alerting on cluster and index events]
is a good source for detailed
information on how watches work. If you are using the UI to create a
threshold watch, take a look at the different watcher actions. If you are
@ -110,9 +110,9 @@ image:management/watcher-ui/images/threshold-alert/threshold-alert-condition.png
Now that the condition is set, you must add an action. The action triggers
when the watch condition is met. For a complete list of actions and how to configure them, see
{stack-ov}/action-conditions.html[Adding conditions to actions].
{ref}/action-conditions.html[Adding conditions to actions].
In this example, youll configure an email action. You must have an {stack-ov}/actions-email.html#configuring-email[email account configured]
In this example, youll configure an email action. You must have an {ref}/actions-email.html#configuring-email[email account configured]
in {es} for this example to work.
. Click *Add action* and select *Email*.
@ -178,7 +178,7 @@ image:management/watcher-ui/images/execution-history.png["Execution history tab"
The *Action statuses* tab lists all actions associated with the watch and
the state of each action. If the action is firing, you can acknowledge the
watch to prevent too many executions of the same action for the same watch.
See {stack-ov}/actions.html#actions-ack-throttle[Acknowledgement and Throttling] for details.
See {ref}/actions.html#actions-ack-throttle[Acknowledgement and throttling] for details.
[role="screenshot"]
image:management/watcher-ui/images/alerts-status.png["Action status tab"]
@ -209,7 +209,7 @@ For more information, see {ref}/query-dsl.html[Query DSL].
On the Watch overview page, click *Create* and choose *Create advanced watch*.
An advanced watch requires a name and ID. Name is a user-friendly way to
identify the watch, and ID refers to the identifier used by {es}. Refer to
{stack-ov}/how-watcher-works.html#watch-definition[Watch definition] for how
{ref}/how-watcher-works.html#watch-definition[Watch definition] for how
to input the watch JSON.
[role="screenshot"]
@ -227,7 +227,7 @@ simulation. Be aware of these implementation details on overrides:
* Action overrides support {ref}/watcher-api-execute-watch.html#watcher-api-execute-watch-action-mode[multiple options].
After starting the simulation, youll see a results screen. For more information
on the fields in the response, see the {ref}//watcher-api-execute-watch.html[Execute Watch API].
on the fields in the response, see the {ref}/watcher-api-execute-watch.html[Execute watch API].
[role="screenshot"]
image:management/watcher-ui/images/advanced-watch/advanced-watch-simulate.png["Create advanced watch"]
@ -237,8 +237,8 @@ image:management/watcher-ui/images/advanced-watch/advanced-watch-simulate.png["C
Refer to these examples for creating an advanced watch:
* {stack-ov}/watch-cluster-status.html[Watch the status of an {es} cluster]
* {stack-ov}/watching-meetup-data.html[Watch event data]
* {ref}/watch-cluster-status.html[Watch the status of an {es} cluster]
* {ref}/watching-meetup-data.html[Watch event data]

View file

@ -47,7 +47,7 @@ include::cluster-alerts-license.asciidoc[]
To receive email notifications for the Cluster Alerts:
. Configure an email account as described in
{stack-ov}/actions-email.html#configuring-email[Configuring email accounts].
{ref}/actions-email.html#configuring-email[Configuring email accounts].
. Configure the
`xpack.monitoring.cluster_alerts.email_notifications.email_address` setting in
`kibana.yml` with your email address.

View file

@ -29,8 +29,8 @@ By default, data is retrieved from the cluster specified in the
from a different cluster, set `xpack.monitoring.elasticsearch.hosts`.
To learn more about typical monitoring architectures,
see {stack-ov}/how-monitoring-works.html[How monitoring works] and
{stack-ov}/monitoring-production.html[Monitoring in a production environment].
see {ref}/how-monitoring-works.html[How monitoring works] and
{ref}/monitoring-production.html[Monitoring in a production environment].
--
. Verify that `xpack.monitoring.ui.enabled` is set to `true`, which is the

View file

@ -4,7 +4,7 @@ see {kibana-ref}/secure-reporting.html[Securing Reporting].
To configure a watch to email reports, you use the `reporting` attachment type
in an `email` action. For more information, see
{stack-ov}/actions-email.html#configuring-email[Configuring Email Accounts].
{ref}/actions-email.html#configuring-email[Configuring email accounts].
For example, the following watch generates a PDF report and emails the report every hour:
@ -46,7 +46,7 @@ PUT _watcher/watch/error_report
<1> You must configure at least one email account to enable Watcher to send email.
For more information, see
{xpack-ref}/actions-email.html#configuring-email[Configuring Email Accounts].
{ref}/actions-email.html#configuring-email[Configuring email accounts].
<2> This is an example POST URL. You can copy and paste the URL for any
report from the Kibana UI.
<3> Optional, default is 40

View file

@ -107,7 +107,7 @@
"@babel/register": "^7.5.5",
"@elastic/charts": "^12.0.2",
"@elastic/datemath": "5.0.2",
"@elastic/eui": "14.2.0",
"@elastic/eui": "14.3.0",
"@elastic/filesaver": "1.1.2",
"@elastic/good": "8.1.1-kibana2",
"@elastic/numeral": "2.3.3",

View file

@ -69,7 +69,6 @@ exports[`rendering render matches snapshot 1`] = `
color="danger"
iconType="alert"
key="0"
size="m"
title="foo"
>
<EuiCodeBlock
@ -86,7 +85,6 @@ Error: foo
color="danger"
iconType="alert"
key="1"
size="m"
title="bar"
>
<EuiCodeBlock

View file

@ -294,7 +294,6 @@ exports[`statusCheckState failed status check - error 1`] = `
/>
<EuiCallOut
color="warning"
size="m"
title="custom error msg"
/>
</React.Fragment>,
@ -410,7 +409,6 @@ exports[`statusCheckState failed status check - no data 1`] = `
/>
<EuiCallOut
color="warning"
size="m"
title="custom error msg"
/>
</React.Fragment>,
@ -637,7 +635,6 @@ exports[`statusCheckState successful status check 1`] = `
/>
<EuiCallOut
color="success"
size="m"
title="custom success msg"
/>
</React.Fragment>,

View file

@ -149,7 +149,6 @@ exports[`bulkCreate should display error message when bulkCreate request fails 1
<EuiCallOut
color="warning"
data-test-subj="loadSavedObjects_failed"
size="m"
title="Request failed, Error: simulated bulkRequest error"
/>
</React.Fragment>,
@ -276,7 +275,6 @@ exports[`bulkCreate should display error message when bulkCreate request fails 1
<EuiCallOut
color="warning"
data-test-subj="loadSavedObjects_failed"
size="m"
title="Request failed, Error: simulated bulkRequest error"
>
<div
@ -451,7 +449,6 @@ exports[`bulkCreate should display success message when bulkCreate is successful
<EuiCallOut
color="success"
data-test-subj="loadSavedObjects_success"
size="m"
title="1 saved objects successfully added"
/>
</React.Fragment>,
@ -612,7 +609,6 @@ exports[`bulkCreate should display success message when bulkCreate is successful
<EuiCallOut
color="success"
data-test-subj="loadSavedObjects_success"
size="m"
title="1 saved objects successfully added"
>
<div

View file

@ -4,7 +4,6 @@ exports[`EmptyState should render normally 1`] = `
<div>
<EuiCallOut
color="warning"
size="m"
title={
<FormattedMessage
defaultMessage="Couldn't find any Elasticsearch data"

View file

@ -56,7 +56,6 @@ exports[`StepTimeField should render "Custom index pattern ID already exists" wh
<EuiCallOut
color="danger"
iconType="cross"
size="m"
title={
<FormattedMessage
defaultMessage="Error"
@ -295,7 +294,6 @@ exports[`StepTimeField should render any error message 1`] = `
<EuiCallOut
color="danger"
iconType="cross"
size="m"
title={
<FormattedMessage
defaultMessage="Error"

View file

@ -5,7 +5,6 @@ exports[`CallOuts should render normally 1`] = `
<EuiCallOut
color="danger"
iconType="cross"
size="m"
title={
<FormattedMessage
defaultMessage="Deprecation languages in use"

View file

@ -32,7 +32,6 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Index Pattern Conflicts"
@ -242,7 +241,6 @@ exports[`Flyout conflicts should handle errors 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Import failed"
@ -271,7 +269,6 @@ exports[`Flyout errors should display unsupported type errors properly 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Import failed"
@ -330,7 +327,6 @@ exports[`Flyout legacy conflicts should allow conflict resolution 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Support for JSON files is going away"
@ -355,7 +351,6 @@ exports[`Flyout legacy conflicts should allow conflict resolution 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Index Pattern Conflicts"
@ -500,7 +495,6 @@ Array [
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Support for JSON files is going away"
@ -520,7 +514,6 @@ Array [
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Index Pattern Conflicts"
@ -553,7 +546,6 @@ Array [
</EuiCallOut>,
<EuiCallOut
color="danger"
size="m"
title={
<FormattedMessage
defaultMessage="Sorry, there was an error"

View file

@ -34,10 +34,7 @@ exports[`Relationships should render dashboards normally 1`] = `
</EuiFlyoutHeader>
<EuiFlyoutBody>
<div>
<EuiCallOut
color="primary"
size="m"
>
<EuiCallOut>
<p>
Here are the saved objects related to MyDashboard. Deleting this dashboard affects its parent objects, but not its children.
</p>
@ -200,7 +197,6 @@ exports[`Relationships should render errors 1`] = `
<EuiFlyoutBody>
<EuiCallOut
color="danger"
size="m"
title={
<FormattedMessage
defaultMessage="Error"
@ -249,10 +245,7 @@ exports[`Relationships should render index patterns normally 1`] = `
</EuiFlyoutHeader>
<EuiFlyoutBody>
<div>
<EuiCallOut
color="primary"
size="m"
>
<EuiCallOut>
<p>
Here are the saved objects related to MyIndexPattern*. Deleting this index-pattern affects its parent objects, but not its children.
</p>
@ -419,10 +412,7 @@ exports[`Relationships should render searches normally 1`] = `
</EuiFlyoutHeader>
<EuiFlyoutBody>
<div>
<EuiCallOut
color="primary"
size="m"
>
<EuiCallOut>
<p>
Here are the saved objects related to MySearch. Deleting this search affects its parent objects, but not its children.
</p>
@ -589,10 +579,7 @@ exports[`Relationships should render visualizations normally 1`] = `
</EuiFlyoutHeader>
<EuiFlyoutBody>
<div>
<EuiCallOut
color="primary"
size="m"
>
<EuiCallOut>
<p>
Here are the saved objects related to MyViz. Deleting this visualization affects its parent objects, but not its children.
</p>

View file

@ -5,7 +5,6 @@ exports[`CallOuts should render normally 1`] = `
<EuiCallOut
color="warning"
iconType="bolt"
size="m"
title={
<FormattedMessage
defaultMessage="Caution: You can break stuff here"

View file

@ -5,7 +5,6 @@ exports[`ScriptingDisabledCallOut should render normally 1`] = `
<EuiCallOut
color="danger"
iconType="alert"
size="m"
title={
<FormattedMessage
defaultMessage="Scripting disabled"

View file

@ -5,7 +5,6 @@ exports[`ScriptingWarningCallOut should render normally 1`] = `
<EuiCallOut
color="warning"
iconType="alert"
size="m"
title={
<FormattedMessage
defaultMessage="Proceed with caution"

View file

@ -22,9 +22,9 @@ import {
EuiAccordion,
EuiToolTip,
EuiButtonIcon,
EuiButtonIconProps,
EuiSpacer,
EuiIconTip,
Color,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -206,7 +206,7 @@ function DefaultEditorAgg({
<EuiToolTip key={icon.id} position="bottom" content={icon.tooltip}>
<EuiButtonIcon
iconType={icon.type}
color={icon.color as Color}
color={icon.color as EuiButtonIconProps['color']}
onClick={icon.onClick}
aria-label={icon.tooltip}
data-test-subj={icon.dataTestSubj}

View file

@ -86,8 +86,8 @@ export class EmbeddableChildPanel extends React.Component<EmbeddableChildPanelPr
}
public render() {
const classes = classNames('embPanel embPanel__content', {
'embPanel__content-isLoading': this.state.loading,
const classes = classNames('embPanel', {
'embPanel-isLoading': this.state.loading,
});
return (

View file

@ -7,6 +7,12 @@
min-height: $euiSizeL + 2px; // + 2px to account for border
position: relative;
&-isLoading {
// completely center the loading indicator
justify-content: center;
align-items: center;
}
// SASSTODO: The inheritence factor stemming from embeddables makes this class hard to change
.embPanel__content {
display: flex;
@ -20,12 +26,6 @@
.embPanel__content--fullWidth {
width: 100%;
}
.embPanel__content-isLoading {
// completely center the loading indicator
justify-content: center;
align-items: center;
}
}
// HEADER
@ -38,13 +38,27 @@
}
.embPanel__title {
@include euiTextTruncate;
@include euiTitle('xxxs');
overflow: hidden;
line-height: 1.5;
flex-grow: 1;
display: flex;
flex-wrap: wrap;
align-items: center;
&:not(:empty) {
padding: ($euiSizeXS * 1.5) $euiSizeS 0;
line-height: $euiSizeL;
padding-left: $euiSizeS;
}
.embPanel__titleInner {
overflow: hidden;
display: flex;
padding-right: $euiSizeS;
}
.embPanel__titleText {
@include euiTextTruncate;
}
}
@ -69,7 +83,7 @@
*/
.embPanel__optionsMenuButton {
background-color: transparentize($euiColorDarkestShade, .9);
background-color: transparentize($euiColorDarkestShade, 0.9);
border-bottom-right-radius: 0;
border-top-left-radius: 0;
@ -78,8 +92,7 @@
}
}
.embPanel
.embPanel__optionsMenuButton {
.embPanel .embPanel__optionsMenuButton {
opacity: 0; /* 1 */
&:focus {
@ -87,8 +100,8 @@
}
}
.embPanel__optionsMenuPopover[class*="-isOpen"],
.embPanel:hover {
.embPanel__optionsMenuPopover[class*='-isOpen'],
.embPanel:hover {
.embPanel__optionsMenuButton {
opacity: 1;
}
@ -127,4 +140,4 @@
overflow: auto;
text-align: center;
padding: $euiSizeS;
}
}

View file

@ -38,6 +38,7 @@ function renderBadges(badges: IAction[], embeddable: IEmbeddable) {
return badges.map(badge => (
<EuiBadge
key={badge.id}
className="embPanel__headerBadge"
iconType={badge.getIconType({ embeddable })}
onClick={() => badge.execute({ embeddable })}
onClickAriaLabel={badge.getDisplayName({ embeddable })}
@ -60,13 +61,13 @@ export function PanelHeader({
badges,
embeddable,
}: PanelHeaderProps) {
const classes = classNames('embPanel__header', {
'embPanel__header--floater': !title || hidePanelTitles,
});
const showTitle = !isViewMode || (title && !hidePanelTitles);
const showPanelBar = badges.length > 0 || showTitle;
const classes = classNames('embPanel__header', {
'embPanel__header--floater': !showPanelBar,
});
if (!showPanelBar) {
return (
<div className={classes}>
@ -107,15 +108,20 @@ export function PanelHeader({
}
)}
>
{showTitle ? `${title} ` : ''}
{renderBadges(badges, embeddable)}
{viewDescr !== '' ? (
<EuiToolTip content={viewDescr} delay="regular" position="right">
<EuiIcon type="iInCircle" />
</EuiToolTip>
{showTitle || viewDescr !== '' ? (
<span className="embPanel__titleInner">
<span className="embPanel__titleText">{title}</span>
{viewDescr !== '' && (
<EuiToolTip content={viewDescr} delay="regular" position="right">
<EuiIcon type="iInCircle" />
</EuiToolTip>
)}
</span>
) : (
''
undefined
)}
{renderBadges(badges, embeddable)}
</div>
<PanelOptionsMenu

View file

@ -94,8 +94,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
});
});
// FLAKY: https://github.com/elastic/kibana/issues/44132
describe.skip('switch index patterns', () => {
describe('switch index patterns', () => {
beforeEach(async () => {
log.debug('Load kibana_sample_data_flights data');
await esArchiver.loadIfNeeded('kibana_sample_data_flights');

View file

@ -49,6 +49,8 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro
await PageObjects.common.navigateToUrl('visualize', 'create?type=metrics');
log.debug('Set absolute time range from "' + fromTime + '" to "' + toTime + '"');
await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
// 2 sec sleep until https://github.com/elastic/kibana/issues/46353 is fixed
await PageObjects.common.sleep(2000);
}
public async checkTabIsLoaded(testSubj: string, name: string) {
@ -413,7 +415,10 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro
}
public async selectIndexPatternTimeField(timeField: string) {
await comboBox.set('metricsIndexPatternFieldsSelect', timeField);
await retry.try(async () => {
await comboBox.clearInputField('metricsIndexPatternFieldsSelect');
await comboBox.set('metricsIndexPatternFieldsSelect', timeField);
});
}
/**

View file

@ -281,6 +281,17 @@ export function ComboBoxProvider({ getService, getPageObjects }: FtrProviderCont
.map(option => $(option).text());
return selectedOptions.length === 1 && selectedOptions[0] === value;
}
/**
* Clears input field
* @param comboBoxSelector data-test-subj selector
*/
public async clearInputField(comboBoxSelector: string): Promise<void> {
log.debug(`comboBox.clearInputField, comboBoxSelector:${comboBoxSelector}`);
const comboBoxElement = await testSubjects.find(comboBoxSelector);
const input = await comboBoxElement.findByTagName('input');
await input.clearValueWithKeyboard();
}
}
return new ComboBox();

View file

@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "14.2.0",
"@elastic/eui": "14.3.0",
"react": "^16.8.0",
"react-dom": "^16.8.0"
}

View file

@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "14.2.0",
"@elastic/eui": "14.3.0",
"react": "^16.8.0"
}
}

View file

@ -8,7 +8,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "14.2.0",
"@elastic/eui": "14.3.0",
"react": "^16.8.0"
},
"scripts": {

View file

@ -8,7 +8,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "14.2.0",
"@elastic/eui": "14.3.0",
"react": "^16.8.0"
},
"scripts": {

View file

@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@elastic/eui": "14.2.0",
"@elastic/eui": "14.3.0",
"react": "^16.8.0",
"react-dom": "^16.8.0"
}

View file

@ -130,23 +130,26 @@ export class CustomizeTimeRangeModal extends Component<CustomizeTimeRangeProps,
</EuiFormRow>
</EuiModalBody>
<EuiModalFooter>
<EuiFlexGroup gutterSize="s" responsive={false}>
<EuiFlexItem>
<EuiButtonEmpty
onClick={this.inheritFromParent}
color="danger"
data-test-subj="removePerPanelTimeRangeButton"
disabled={this.state.inheritTimeRange}
>
{i18n.translate(
'xpack.advancedUiActions.customizePanelTimeRange.modal.removeButtonTitle',
{
defaultMessage: 'Remove',
}
)}
</EuiButtonEmpty>
<EuiFlexGroup gutterSize="s" responsive={false} justifyContent="spaceBetween">
<EuiFlexItem grow={true}>
<div>
<EuiButtonEmpty
onClick={this.inheritFromParent}
color="danger"
data-test-subj="removePerPanelTimeRangeButton"
disabled={this.state.inheritTimeRange}
flush="left"
>
{i18n.translate(
'xpack.advancedUiActions.customizePanelTimeRange.modal.removeButtonTitle',
{
defaultMessage: 'Remove',
}
)}
</EuiButtonEmpty>
</div>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={this.cancel} data-test-subj="cancelPerPanelTimeRangeButton">
{i18n.translate(
'xpack.advancedUiActions.customizePanelTimeRange.modal.cancelButtonTitle',
@ -156,7 +159,7 @@ export class CustomizeTimeRangeModal extends Component<CustomizeTimeRangeProps,
)}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton data-test-subj="addPerPanelTimeRangeButton" onClick={this.addToPanel} fill>
{this.state.inheritTimeRange
? i18n.translate(

View file

@ -109,12 +109,22 @@ export interface SymbolSearchRequest extends SearchRequest {
repoScope?: RepositoryUri[];
}
export interface CodeIntegrationRequest {
repoUri: RepositoryUri;
revision?: string;
export interface StackTraceItem {
filePath: string;
lineNumStart: number;
lineNumEnd?: number;
// We could add more in here in the future, e.g. qname.
}
export interface ResolveSnippetsIntegrationRequest extends CodeIntegrationRequest {
export interface StackTraceSnippetsRequest {
repoUris: RepositoryUri[];
revision?: string; // Not used for now.
stacktraceItems: StackTraceItem[];
}
export interface ResolveSnippetsRequest {
repoUris: RepositoryUri[];
revision?: string; // Not used for now.
filePath: string;
lineNumStart: number;
lineNumEnd?: number;
@ -134,7 +144,7 @@ export interface RepositorySearchResult extends SearchResult {
}
export interface SymbolSearchResult extends SearchResult {
// TODO: we migit need an additional data structure for symbol search result.
// TODO: we might need an additional data structure for symbol search result.
symbols: DetailSymbolInformation[];
}
@ -189,6 +199,7 @@ export interface CommitSearchResult extends DocumentSearchResult {
export interface IntegrationsSearchResult extends SearchResult {
results?: SearchResultItem[];
fallback: boolean;
}
export interface SourceLocation {

View file

@ -11,7 +11,9 @@ import {
CommitSearchRequest,
DocumentSearchRequest,
RepositorySearchRequest,
ResolveSnippetsIntegrationRequest,
ResolveSnippetsRequest,
StackTraceItem,
StackTraceSnippetsRequest,
SymbolSearchRequest,
} from '../../model';
import { Logger } from '../log';
@ -158,27 +160,29 @@ export function documentSearchRoute(router: CodeServerRouter, log: Logger) {
// * filePath: the path of the file.
// * lineNumStart: the start line number of the snippet.
// * lineNumEnd: Optional. The end line number of the snippet.
// We can always add more context for snippet resolution in the future.
router.route({
path: '/api/code/integration/snippets',
method: 'GET',
method: 'POST',
async handler(req: RequestFacade) {
const { repoUri, revision, filePath, lineNum, lineNumEnd } = req.query as RequestQueryFacade;
try {
const integRequest: ResolveSnippetsIntegrationRequest = {
repoUri: repoUri as string,
revision: revision ? (revision as string) : undefined,
filePath: filePath as string,
lineNumStart: lineNum ? parseInt(lineNum as string, 10) : 0,
lineNumEnd: lineNumEnd ? parseInt(lineNumEnd as string, 10) : undefined,
};
const integClient = new IntegrationsSearchClient(new EsClientWithRequest(req), log);
const res = await integClient.resolveSnippets(integRequest);
return res;
} catch (error) {
return Boom.internal(`Invalid request for resovling snippets.`);
}
const reqs: StackTraceSnippetsRequest[] = (req.payload as any).requests;
return await Promise.all(
reqs.map((stacktraceReq: StackTraceSnippetsRequest) => {
const integClient = new IntegrationsSearchClient(new EsClientWithRequest(req), log);
return Promise.all(
stacktraceReq.stacktraceItems.map((stacktrace: StackTraceItem) => {
const integrationReq: ResolveSnippetsRequest = {
repoUris: stacktraceReq.repoUris,
revision: stacktraceReq.revision,
filePath: stacktrace.filePath,
lineNumStart: stacktrace.lineNumStart,
lineNumEnd: stacktrace.lineNumEnd,
};
return integClient.resolveSnippets(integrationReq);
})
);
})
);
},
});
}

View file

@ -9,4 +9,4 @@ export * from './document_search_client';
export * from './repository_search_client';
export * from './symbol_search_client';
export * from './repository_object_client';
export * from './integraions_search_client';
export * from './integrations_search_client';

View file

@ -8,7 +8,7 @@ import sinon from 'sinon';
import { AnyObject, EsClient } from '../lib/esqueue';
import { Logger } from '../log';
import { IntegrationsSearchClient } from './integraions_search_client';
import { IntegrationsSearchClient } from './integrations_search_client';
let integSearchClient: IntegrationsSearchClient;
let esClient;
@ -66,6 +66,24 @@ const mockSearchResults = [
},
},
},
// 3. The third response is a valid DocumentSearchResult with 0 doc
{
took: 1,
hits: {
total: {
value: 0,
},
hits: [],
},
aggregations: {
repoUri: {
buckets: [],
},
language: {
buckets: [],
},
},
},
];
// Setup the mock EsClient.
@ -92,13 +110,14 @@ beforeEach(() => {
test('Document search', async () => {
// 1. The first response should have 1 result.
const responseWithResult = await integSearchClient.resolveSnippets({
repoUri: 'github.com/Microsoft/TypeScript-Node-Starter',
repoUris: ['github.com/Microsoft/TypeScript-Node-Starter'],
filePath: 'src/types/express-flash.d.ts',
lineNumStart: 3,
lineNumEnd: 7,
});
expect(responseWithResult).toEqual(
expect.objectContaining({
fallback: false,
took: 1,
total: 1,
results: [
@ -130,11 +149,12 @@ test('Document search', async () => {
// 2. The first response should have 0 results.
const responseWithEmptyResult = await integSearchClient.resolveSnippets({
repoUri: 'github.com/Microsoft/TypeScript-Node-Starter',
repoUris: ['github.com/Microsoft/TypeScript-Node-Starter'],
filePath: 'src/types/foo-bar',
lineNumStart: 3,
lineNumEnd: 7,
});
expect(responseWithEmptyResult.results!.length).toEqual(0);
expect(responseWithEmptyResult.total).toEqual(0);
expect(responseWithEmptyResult.fallback).toBeTruthy();
});

View file

@ -7,7 +7,7 @@
import {
Document,
IntegrationsSearchResult,
ResolveSnippetsIntegrationRequest,
ResolveSnippetsRequest,
SearchResultItem,
SourceHit,
} from '../../model';
@ -21,13 +21,12 @@ export class IntegrationsSearchClient extends DocumentSearchClient {
super(client, log);
}
public async resolveSnippets(
req: ResolveSnippetsIntegrationRequest
): Promise<IntegrationsSearchResult> {
const { repoUri, filePath, lineNumStart, lineNumEnd } = req;
const index = DocumentSearchIndexWithScope([repoUri]);
public async resolveSnippets(req: ResolveSnippetsRequest): Promise<IntegrationsSearchResult> {
const { repoUris, filePath, lineNumStart, lineNumEnd } = req;
const index = DocumentSearchIndexWithScope(repoUris);
const rawRes = await this.client.search({
let fallback = false;
let rawRes = await this.client.search({
index,
body: {
query: {
@ -39,15 +38,46 @@ export class IntegrationsSearchClient extends DocumentSearchClient {
},
},
});
if (rawRes.hits.hits.length === 0) {
// Fall back with match query with gauss score normalization on path length.
rawRes = await this.client.search({
index,
body: {
query: {
script_score: {
query: {
term: {
'path.hierarchy': {
value: filePath,
},
},
},
script: {
source:
"decayNumericGauss(params.origin, params.scale, params.offset, params.decay, doc['path.keyword'].value.length())",
params: {
origin: filePath.length,
scale: 20,
offset: 0,
decay: 0.8,
},
},
},
},
},
});
fallback = true;
}
const total = rawRes.hits.total.value;
const hits: any[] = rawRes.hits.hits;
const results: SearchResultItem[] = hits.map(hit => {
const doc: Document = hit._source;
const { path, language } = doc;
const { repoUri: uri, path, language } = doc;
const sourceContent = this.getSnippetContent(doc, lineNumStart, lineNumEnd);
const item: SearchResultItem = {
uri: repoUri,
uri,
filePath: path,
language: language!,
hits: 1,
@ -55,9 +85,10 @@ export class IntegrationsSearchClient extends DocumentSearchClient {
};
return item;
});
const total = rawRes.hits.total.value;
return {
results,
fallback,
took: rawRes.took,
total,
};

View file

@ -242,7 +242,6 @@ exports[`ilm summary extension should return extension when index has lifecycle
<EuiCallOut
color="danger"
iconType="cross"
size="m"
title={
<FormattedMessage
defaultMessage="Index lifecycle error"

View file

@ -1254,7 +1254,6 @@ exports[`UploadLicense should display an error when ES says license is expired 1
<EuiCallOut
className="euiForm__errors"
color="danger"
size="m"
title="Please address the errors in your form."
>
<div
@ -1706,7 +1705,6 @@ exports[`UploadLicense should display an error when ES says license is invalid 1
<EuiCallOut
className="euiForm__errors"
color="danger"
size="m"
title="Please address the errors in your form."
>
<div
@ -2158,7 +2156,6 @@ exports[`UploadLicense should display an error when submitting invalid JSON 1`]
<EuiCallOut
className="euiForm__errors"
color="danger"
size="m"
title="Please address the errors in your form."
>
<div
@ -2606,7 +2603,6 @@ exports[`UploadLicense should display error when ES returns error 1`] = `
<EuiCallOut
className="euiForm__errors"
color="danger"
size="m"
title="Please address the errors in your form."
>
<div

View file

@ -4,7 +4,6 @@ exports[`AlertCallOut component renders expected component 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="Only pipelines created in Kibana Management appear here"
>
<p>

View file

@ -4,7 +4,6 @@ exports[`Should render errors when layer has errors 1`] = `
<Fragment>
<EuiCallOut
color="warning"
size="m"
title="Unable to load layer"
>
<p

View file

@ -110,10 +110,8 @@ exports[`AnnotationsTable Initialization with job config prop. 1`] = `
exports[`AnnotationsTable Minimal initialization without props. 1`] = `
<EuiCallOut
color="primary"
iconType="iInCircle"
role="alert"
size="m"
title={
<FormattedMessage
defaultMessage="No annotations created for this job"

View file

@ -192,7 +192,6 @@ exports[`RuleEditorFlyout renders the flyout after adding a condition to a rule
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Rerun job"
@ -459,7 +458,6 @@ exports[`RuleEditorFlyout renders the flyout after setting the rule to edit 1`]
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Rerun job"
@ -704,7 +702,6 @@ exports[`RuleEditorFlyout renders the flyout for creating a rule with conditions
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Rerun job"

View file

@ -211,10 +211,8 @@ exports[`Overview that overview page shows a message if there is no beats data 1
stats={Array []}
/>
<EuiCallOut
color="primary"
data-test-subj="noRecentActivityMessage"
iconType="gear"
size="m"
title="Hi there! This area is where your latest Beats activity would show up, but you don't seem to have any activity within the last day."
/>
<EuiSpacer

View file

@ -2,7 +2,6 @@
exports[`Logs should render a link to filter by cluster uuid 1`] = `
<EuiCallOut
color="primary"
iconType="loggingApp"
size="m"
title="Want to see more log entries?"
@ -29,7 +28,6 @@ exports[`Logs should render a link to filter by cluster uuid 1`] = `
exports[`Logs should render a link to filter by cluster uuid and index uuid 1`] = `
<EuiCallOut
color="primary"
iconType="loggingApp"
size="m"
title="Want to see more log entries?"
@ -56,7 +54,6 @@ exports[`Logs should render a link to filter by cluster uuid and index uuid 1`]
exports[`Logs should render a link to filter by cluster uuid and node uuid 1`] = `
<EuiCallOut
color="primary"
iconType="loggingApp"
size="m"
title="Want to see more log entries?"
@ -284,7 +281,6 @@ exports[`Logs should render normally 1`] = `
size="m"
/>
<EuiCallOut
color="primary"
iconType="loggingApp"
size="m"
title="Want to see more log entries?"

View file

@ -4,7 +4,6 @@ exports[`Logs should render a default message 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No log data found"
>
<p>
@ -35,7 +34,6 @@ exports[`Logs should render with a no cluster found reason 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No logs for this cluster"
>
<p>
@ -62,7 +60,6 @@ exports[`Logs should render with a no index found reason 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No logs for this index"
>
<p>
@ -89,7 +86,6 @@ exports[`Logs should render with a no index pattern found reason 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No log data found"
>
<p>
@ -116,7 +112,6 @@ exports[`Logs should render with a no node found reason 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No logs for this Elasticsearch node"
>
<p>
@ -143,7 +138,6 @@ exports[`Logs should render with a no type found reason 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No logs for Elasticsearch"
>
<p>
@ -170,7 +164,6 @@ exports[`Logs should render with a time period reason 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No logs for the selected time"
>
<p>
@ -187,7 +180,6 @@ exports[`Logs should render with a time period reason for both scenarios 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title="No logs for the selected time"
>
<p>

View file

@ -5,7 +5,6 @@ exports[`<SpaceAwarePrivilegeSection> with user profile disabling "manageSpaces"
color="danger"
data-test-subj="userCannotManageSpacesCallout"
iconType="alert"
size="m"
title={
<p>
<FormattedMessage

View file

@ -67,7 +67,6 @@ exports[`ConfirmDeleteModal renders as expected 1`] = `
<EuiSpacer />
<EuiCallOut
color="warning"
size="m"
>
<EuiText>
<FormattedMessage

View file

@ -8,7 +8,6 @@ exports[`AdvancedSettingsSubtitle renders as expected 1`] = `
<EuiCallOut
color="primary"
iconType="spacesApp"
size="m"
title={
<p>
<FormattedMessage

View file

@ -25,7 +25,6 @@ exports[`CheckupTab render with deprecations 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Back up your indices now"
@ -312,7 +311,6 @@ exports[`CheckupTab render with error 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Back up your indices now"
@ -382,7 +380,6 @@ exports[`CheckupTab render without deprecations 1`] = `
<EuiCallOut
color="warning"
iconType="help"
size="m"
title={
<FormattedMessage
defaultMessage="Back up your indices now"

View file

@ -6,7 +6,6 @@ exports[`ChecklistFlyout renders 1`] = `
<EuiCallOut
color="warning"
iconType="alert"
size="m"
title={
<FormattedMessage
defaultMessage="Index is unable to ingest, update, or delete documents while reindexing"

View file

@ -6,7 +6,6 @@ exports[`WarningsFlyoutStep renders 1`] = `
<EuiCallOut
color="danger"
iconType="alert"
size="m"
title={
<FormattedMessage
defaultMessage="This index requires destructive changes that can't be undone"

View file

@ -4,7 +4,6 @@ exports[`OverviewPageParsingErrorCallout renders without errors when a valid err
<EuiCallOut
color="danger"
iconType="alert"
size="m"
title="Parsing error"
>
<p>
@ -27,7 +26,6 @@ exports[`OverviewPageParsingErrorCallout renders without errors when an error wi
<EuiCallOut
color="danger"
iconType="alert"
size="m"
title="Parsing error"
>
<p>

View file

@ -184,7 +184,7 @@
"@babel/runtime": "^7.5.5",
"@elastic/ctags-langserver": "^0.1.10",
"@elastic/datemath": "5.0.2",
"@elastic/eui": "14.2.0",
"@elastic/eui": "14.3.0",
"@elastic/javascript-typescript-langserver": "^0.3.3",
"@elastic/lsp-extension": "^0.1.2",
"@elastic/maki": "6.1.0",

View file

@ -1019,10 +1019,10 @@
tabbable "^1.1.0"
uuid "^3.1.0"
"@elastic/eui@14.2.0":
version "14.2.0"
resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-14.2.0.tgz#d6368250e7261c63c06443d3cf3f7cf800916ff2"
integrity sha512-6nCV/Q2Ek3zTUj549+cFFx5rpx4ZZ2pjmspPsBhUwsn685qzAPsCv4WB40u4mWBZtMRZagBN2q2M2YxZHSPBLw==
"@elastic/eui@14.3.0":
version "14.3.0"
resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-14.3.0.tgz#256e1af8f6b15717904f8959742a23b3495ff0bb"
integrity sha512-gAbPNezBmndInYqqw6EvRYLn2VMYQgYuPQYA5UZ7TyHzwvoBiMpUw5nFzYhS2A/Xcmq/ON5Mu8RY3LGRAVBOvQ==
dependencies:
"@types/lodash" "^4.14.116"
"@types/numeral" "^0.0.25"