Skip to content

Commit

Permalink
Merge branch 'DianaDerevyankina' into Diana/57813-vega
Browse files Browse the repository at this point in the history
  • Loading branch information
DianaDerevyankina committed Jul 10, 2020
2 parents e7bed7c + 12ec1be commit d107138
Show file tree
Hide file tree
Showing 17 changed files with 207 additions and 26 deletions.
2 changes: 1 addition & 1 deletion docs/apm/api.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ include::api.asciidoc[tag=using-the-APIs]
[%collapsible%open]
======
`version` :::
(required, string) Name of service.
(required, string) Version of service.
`environment` :::
(optional, string) Environment of service.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n';
import { debounce } from 'lodash';
import { parse } from 'query-string';
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
import { useUIAceKeyboardMode } from '../../../../../../../es_ui_shared/public';
import { ace } from '../../../../../../../es_ui_shared/public';
// @ts-ignore
import { retrieveAutoCompleteInfo, clearSubscriptions } from '../../../../../lib/mappings/mappings';
import { ConsoleMenu } from '../../../../components';
Expand All @@ -38,6 +38,8 @@ import { subscribeResizeChecker } from '../subscribe_console_resize_checker';
import { applyCurrentSettings } from './apply_editor_settings';
import { registerCommands } from './keyboard_shortcuts';

const { useUIAceKeyboardMode } = ace;

export interface EditorProps {
initialTextValue: string;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.kbnUiAceKeyboardHint {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: transparentize($euiColorEmptyShade, 0.3);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
opacity: 0;

&:focus {
opacity: 1;
border: 2px solid $euiColorPrimary;
z-index: $euiZLevel1;
}

&.kbnUiAceKeyboardHint-isInactive {
display: none;
}
}
20 changes: 20 additions & 0 deletions src/plugins/es_ui_shared/__packages_do_not_import__/ace/index.ts
Original file line number Diff line number Diff line change
@@ -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 { useUIAceKeyboardMode } from './use_ui_ace_keyboard_mode';
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/

import React, { useEffect, useRef } from 'react';
import * as ReactDOM from 'react-dom';
import { keys, EuiText } from '@elastic/eui';

import './_ui_ace_keyboard_mode.scss';

const OverlayText = () => (
// The point of this element is for accessibility purposes, so ignore eslint error
// in this case
Expand Down
20 changes: 20 additions & 0 deletions src/plugins/es_ui_shared/public/ace/index.ts
Original file line number Diff line number Diff line change
@@ -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 { useUIAceKeyboardMode } from '../../__packages_do_not_import__/ace';
5 changes: 2 additions & 3 deletions src/plugins/es_ui_shared/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
import * as Forms from './forms';
import * as Monaco from './monaco';
import * as ace from './ace';

export { JsonEditor, OnJsonEditorUpdateHandler } from './components/json_editor';

Expand All @@ -41,8 +42,6 @@ export {

export { indices } from './indices';

export { useUIAceKeyboardMode } from './use_ui_ace_keyboard_mode';

export {
installXJsonMode,
XJsonMode,
Expand All @@ -66,7 +65,7 @@ export {
useAuthorizationContext,
} from './authorization';

export { Monaco, Forms };
export { Monaco, Forms, ace };

export { extractQueryParams } from './url';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const AnomalyDetection = () => {
<EuiText>
{i18n.translate('xpack.apm.settings.anomalyDetection.descriptionText', {
defaultMessage:
'The Machine Learning anomaly detection integration enables application health status indicators in the Service map by identifying transaction duration anomalies.',
'The Machine Learning anomaly detection integration enables application health status indicators for each configured environment in the Service map by identifying transaction duration anomalies.',
})}
</EuiText>
<EuiSpacer size="l" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const JobsList = ({
{i18n.translate(
'xpack.apm.settings.anomalyDetection.jobList.addEnvironments',
{
defaultMessage: 'Add environments',
defaultMessage: 'Create ML Job',
}
)}
</EuiButton>
Expand All @@ -108,7 +108,7 @@ export const JobsList = ({
<EuiText>
<FormattedMessage
id="xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText"
defaultMessage="Manage existing anomaly detection jobs in {mlJobsLink}."
defaultMessage="To add anomaly detection to a new environment, create a machine learning job. Existing machine learning jobs can be managed in {mlJobsLink}."
values={{
mlJobsLink: (
<MLLink path="jobs">
Expand Down
16 changes: 16 additions & 0 deletions x-pack/plugins/infra/public/utils/datemath.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ describe('extendDatemath()', () => {
diffUnit: 'y',
});
});

it('Returns no difference if the next value would result in an epoch smaller than 0', () => {
// FIXME: Test will fail in ~551 years
expect(extendDatemath('now-500y', 'before')).toBeUndefined();

expect(
extendDatemath('1970-01-01T00:00:00.000Z', 'before', '1970-01-01T00:00:00.001Z')
).toBeUndefined();
});
});

describe('with a positive operator', () => {
Expand Down Expand Up @@ -573,6 +582,13 @@ describe('extendDatemath()', () => {
diffUnit: 'y',
});
});

it('Returns no difference if the next value would result in an epoch bigger than the max JS date', () => {
expect(extendDatemath('now+275760y', 'after')).toBeUndefined();
expect(
extendDatemath('+275760-09-13T00:00:00.000Z', 'after', '+275760-09-12T23:59:59.999Z')
).toBeUndefined();
});
});
});
});
Expand Down
43 changes: 32 additions & 11 deletions x-pack/plugins/infra/public/utils/datemath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import dateMath, { Unit } from '@elastic/datemath';

const JS_MAX_DATE = 8640000000000000;

export function isValidDatemath(value: string): boolean {
const parsedValue = dateMath.parse(value);
return !!(parsedValue && parsedValue.isValid());
Expand Down Expand Up @@ -136,18 +138,24 @@ function extendRelativeDatemath(
// if `diffAmount` is not an integer after normalization, express the difference in the original unit
const shouldKeepDiffUnit = diffAmount % 1 !== 0;

return {
value: `now${operator}${normalizedAmount}${normalizedUnit}`,
diffUnit: shouldKeepDiffUnit ? unit : newUnit,
diffAmount: shouldKeepDiffUnit ? Math.abs(newAmount - parsedAmount) : diffAmount,
};
const nextValue = `now${operator}${normalizedAmount}${normalizedUnit}`;

if (isDateInRange(nextValue)) {
return {
value: nextValue,
diffUnit: shouldKeepDiffUnit ? unit : newUnit,
diffAmount: shouldKeepDiffUnit ? Math.abs(newAmount - parsedAmount) : diffAmount,
};
} else {
return undefined;
}
}

function extendAbsoluteDatemath(
value: string,
direction: 'before' | 'after',
oppositeEdge: string
): DatemathExtension {
): DatemathExtension | undefined {
const valueTimestamp = datemathToEpochMillis(value)!;
const oppositeEdgeTimestamp = datemathToEpochMillis(oppositeEdge)!;
const actualTimestampDiff = Math.abs(valueTimestamp - oppositeEdgeTimestamp);
Expand All @@ -159,11 +167,15 @@ function extendAbsoluteDatemath(
? valueTimestamp - normalizedTimestampDiff
: valueTimestamp + normalizedTimestampDiff;

return {
value: new Date(newValue).toISOString(),
diffUnit: normalizedDiff.unit,
diffAmount: normalizedDiff.amount,
};
if (isDateInRange(newValue)) {
return {
value: new Date(newValue).toISOString(),
diffUnit: normalizedDiff.unit,
diffAmount: normalizedDiff.amount,
};
} else {
return undefined;
}
}

const CONVERSION_RATIOS: Record<string, Array<[Unit, number]>> = {
Expand Down Expand Up @@ -265,3 +277,12 @@ export function normalizeDate(amount: number, unit: Unit): { amount: number; uni
// Cannot go one one unit above. Return as it is
return { amount, unit };
}

function isDateInRange(date: string | number): boolean {
try {
const epoch = typeof date === 'string' ? datemathToEpochMillis(date) ?? -1 : date;
return epoch >= 0 && epoch <= JS_MAX_DATE;
} catch {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const getEmptySections = ({ core }: { core: AppMountContext['core'] }): I
icon: 'watchesApp',
description: i18n.translate('xpack.observability.emptySection.apps.alert.description', {
defaultMessage:
'503 errors stacking up. Applications not responding. CPU and RAM utilization jumping. See these warnings as they happen - not as part of the post-mortem.',
'Are 503 errors stacking up? Are services responding? Is CPU and RAM utilization jumping? See warnings as they happennot as part of the post-mortem.',
}),
linkTitle: i18n.translate('xpack.observability.emptySection.apps.alert.link', {
defaultMessage: 'Create alert',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import { EuiScreenReaderOnly } from '@elastic/eui';
import { Editor as AceEditor } from 'brace';

import { initializeEditor } from './init_editor';
import { useUIAceKeyboardMode } from '../../../../../../src/plugins/es_ui_shared/public';
import { ace } from '../../../../../../src/plugins/es_ui_shared/public';

const { useUIAceKeyboardMode } = ace;

type EditorShim = ReturnType<typeof createEditorShim>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { useSelector } from 'react-redux';

import { TestProviders, mockTimelineModel } from '../../../../../common/mock';
import { DEFAULT_ACTIONS_COLUMN_WIDTH } from '../constants';
import * as i18n from '../translations';

import { Actions } from '.';
import { TimelineType } from '../../../../../../common/types/timeline';

jest.mock('react-redux', () => {
const origin = jest.requireActual('react-redux');
Expand Down Expand Up @@ -202,6 +204,73 @@ describe('Actions', () => {
expect(toggleShowNotes).toBeCalled();
});

test('it renders correct tooltip for NotesButton - timeline', () => {
const toggleShowNotes = jest.fn();

const wrapper = mount(
<TestProviders>
<Actions
actionsColumnWidth={DEFAULT_ACTIONS_COLUMN_WIDTH}
associateNote={jest.fn()}
checked={false}
expanded={false}
eventId="abc"
eventIsPinned={false}
getNotesByIds={jest.fn()}
loading={false}
loadingEventIds={[]}
noteIds={[]}
onEventToggled={jest.fn()}
onPinClicked={jest.fn()}
onRowSelected={jest.fn()}
showCheckboxes={false}
showNotes={false}
toggleShowNotes={toggleShowNotes}
updateNote={jest.fn()}
/>
</TestProviders>
);

expect(wrapper.find('[data-test-subj="add-note"]').prop('toolTip')).toEqual(i18n.NOTES_TOOLTIP);
});

test('it renders correct tooltip for NotesButton - timeline template', () => {
(useSelector as jest.Mock).mockReturnValue({
...mockTimelineModel,
timelineType: TimelineType.template,
});
const toggleShowNotes = jest.fn();

const wrapper = mount(
<TestProviders>
<Actions
actionsColumnWidth={DEFAULT_ACTIONS_COLUMN_WIDTH}
associateNote={jest.fn()}
checked={false}
expanded={false}
eventId="abc"
eventIsPinned={false}
getNotesByIds={jest.fn()}
loading={false}
loadingEventIds={[]}
noteIds={[]}
onEventToggled={jest.fn()}
onPinClicked={jest.fn()}
onRowSelected={jest.fn()}
showCheckboxes={false}
showNotes={false}
toggleShowNotes={toggleShowNotes}
updateNote={jest.fn()}
/>
</TestProviders>
);

expect(wrapper.find('[data-test-subj="add-note"]').prop('toolTip')).toEqual(
i18n.NOTES_DISABLE_TOOLTIP
);
(useSelector as jest.Mock).mockReturnValue(mockTimelineModel);
});

test('it does NOT render a pin button when isEventViewer is true', () => {
const onPinClicked = jest.fn();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { EuiButtonIcon, EuiCheckbox, EuiLoadingSpinner, EuiToolTip } from '@elas

import { Note } from '../../../../../common/lib/note';
import { StoreState } from '../../../../../common/store/types';
import { TimelineType } from '../../../../../../common/types/timeline';

import { TimelineModel } from '../../../../store/timeline/model';

Expand Down Expand Up @@ -170,7 +171,11 @@ export const Actions = React.memo<Props>(
status={timeline.status}
timelineType={timeline.timelineType}
toggleShowNotes={toggleShowNotes}
toolTip={timeline.timelineType ? i18n.NOTES_DISABLE_TOOLTIP : i18n.NOTES_TOOLTIP}
toolTip={
timeline.timelineType === TimelineType.template
? i18n.NOTES_DISABLE_TOOLTIP
: i18n.NOTES_TOOLTIP
}
updateNote={updateNote}
/>
</EventsTdContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ describe('helpers', () => {
eventHasNotes: false,
timelineType: TimelineType.template,
})
).toEqual('This event cannot be pinned because it is filtered by a timeline template');
).toEqual('This event may not be pinned while editing a template timeline');
});
});

Expand Down
Loading

0 comments on commit d107138

Please sign in to comment.