[Uptime] Implement EuiSuperDatePicker (#28217) (#29136)

* Implement EuiSuperDatePicker, update components to use new state props.

* Update backend to accept values from EuiSuperDatePicker.

* Fix issues with implementation of super date picker.

* Fix bug in autorefresh enablement.

* Delete obsolete code.

* Fix broken types.

* Add comment to remind to delete code once it's obsolete.

* Fix types.

* Remove unused import.

* Add polling for ErrorList component.

* Update broken unit tests.

* Change default autorefresh interval.

* Add comments based on PR feedback.

* Add comment based on PR feedback.
This commit is contained in:
Justin Kambic 2019-01-22 19:06:29 -05:00 committed by GitHub
parent f4f956e3b2
commit 9990165366
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 3179 additions and 853 deletions

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,6 @@
*/
export interface UMGqlRange {
dateRangeStart: number;
dateRangeEnd: number;
dateRangeStart: string;
dateRangeEnd: string;
}

View file

@ -43,7 +43,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -53,7 +53,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
}
@ -88,7 +88,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -98,7 +98,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -120,25 +120,41 @@
{
"name": "dateRangeStart",
"description": "",
"type": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null },
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
{
"name": "dateRangeEnd",
"description": "",
"type": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null },
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
{
"name": "downCount",
"description": "",
"type": { "kind": "SCALAR", "name": "Int", "ofType": null },
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "Int", "ofType": null }
},
"defaultValue": null
},
{
"name": "windowSize",
"description": "",
"type": { "kind": "SCALAR", "name": "Int", "ofType": null },
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "Int", "ofType": null }
},
"defaultValue": null
},
{
@ -159,19 +175,31 @@
{
"name": "monitorId",
"description": "",
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
{
"name": "dateRangeStart",
"description": "",
"type": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null },
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
{
"name": "dateRangeEnd",
"description": "",
"type": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null },
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
}
],
@ -193,7 +221,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -203,7 +231,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -240,7 +268,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -250,7 +278,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
}
@ -269,7 +297,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -279,7 +307,7 @@
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
},
"defaultValue": null
},
@ -324,16 +352,6 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "UnsignedInteger",
"description": "",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "PingResults",
@ -1345,6 +1363,16 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "UnsignedInteger",
"description": "",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "LatestMonitorsResult",

View file

@ -393,51 +393,51 @@ export interface AllPingsQueryArgs {
status?: string | null;
dateRangeStart: UnsignedInteger;
dateRangeStart: string;
dateRangeEnd: UnsignedInteger;
dateRangeEnd: string;
}
export interface GetMonitorsQueryArgs {
dateRangeStart: UnsignedInteger;
dateRangeStart: string;
dateRangeEnd: UnsignedInteger;
dateRangeEnd: string;
filters?: string | null;
}
export interface GetSnapshotQueryArgs {
dateRangeStart?: UnsignedInteger | null;
dateRangeStart: string;
dateRangeEnd?: UnsignedInteger | null;
dateRangeEnd: string;
downCount?: number | null;
downCount: number;
windowSize?: number | null;
windowSize: number;
filters?: string | null;
}
export interface GetMonitorChartsDataQueryArgs {
monitorId?: string | null;
monitorId: string;
dateRangeStart?: UnsignedInteger | null;
dateRangeStart: string;
dateRangeEnd?: UnsignedInteger | null;
dateRangeEnd: string;
}
export interface GetLatestMonitorsQueryArgs {
dateRangeStart: UnsignedInteger;
dateRangeStart: string;
dateRangeEnd: UnsignedInteger;
dateRangeEnd: string;
monitorId?: string | null;
}
export interface GetFilterBarQueryArgs {
dateRangeStart: UnsignedInteger;
dateRangeStart: string;
dateRangeEnd: UnsignedInteger;
dateRangeEnd: string;
}
export interface GetErrorsListQueryArgs {
dateRangeStart: UnsignedInteger;
dateRangeStart: string;
dateRangeEnd: UnsignedInteger;
dateRangeEnd: string;
filters?: string | null;
}

View file

@ -9,22 +9,19 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { Fragment } from 'react';
import { Query } from 'react-apollo';
import { UptimeCommonProps } from '../../../uptime_app';
import { getDocCountQuery } from './get_doc_count';
interface EmptyStateProps {
autorefreshInterval: number;
autorefreshEnabled: boolean;
children: JSX.Element[];
}
export const EmptyState = ({
autorefreshInterval,
autorefreshEnabled,
children,
}: EmptyStateProps) => (
type Props = EmptyStateProps & UptimeCommonProps;
export const EmptyState = ({ autorefreshInterval, autorefreshIsPaused, children }: Props) => (
<Query
query={getDocCountQuery}
pollInterval={autorefreshEnabled ? autorefreshInterval : undefined}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
>
{({ loading, error, data }) => {
if (loading) {

View file

@ -12,16 +12,27 @@ import moment from 'moment';
import React, { Fragment } from 'react';
import { Query } from 'react-apollo';
import { Link } from 'react-router-dom';
import { UptimeCommonProps } from '../../../uptime_app';
import { getErrorListQuery } from './get_error_list';
interface ErrorListProps {
dateRangeStart: number;
dateRangeEnd: number;
filters?: string;
}
export const ErrorList = ({ dateRangeStart, dateRangeEnd, filters }: ErrorListProps) => (
<Query query={getErrorListQuery} variables={{ dateRangeStart, dateRangeEnd, filters }}>
type Props = ErrorListProps & UptimeCommonProps;
export const ErrorList = ({
dateRangeStart,
dateRangeEnd,
filters,
autorefreshInterval,
autorefreshIsPaused,
}: Props) => (
<Query
query={getErrorListQuery}
variables={{ dateRangeStart, dateRangeEnd, filters }}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
>
{({ loading, error, data }) => {
if (error) {
return i18n.translate('xpack.uptime.errorList.errorMessage', {

View file

@ -7,11 +7,7 @@
import gql from 'graphql-tag';
export const getErrorListQuery = gql`
query ErrorList(
$dateRangeStart: UnsignedInteger!
$dateRangeEnd: UnsignedInteger!
$filters: String
) {
query ErrorList($dateRangeStart: String!, $dateRangeEnd: String!, $filters: String) {
errorList: getErrorsList(
dateRangeStart: $dateRangeStart
dateRangeEnd: $dateRangeEnd

View file

@ -10,19 +10,20 @@ import { i18n } from '@kbn/i18n';
import { take } from 'lodash';
import React from 'react';
import { Query } from 'react-apollo';
import { UptimeCommonProps } from '../../../uptime_app';
import { getFilterBarQuery } from './get_filter_bar';
import { filterBarSearchSchema } from './search_schema';
interface FilterBarProps {
dateRangeStart: number;
dateRangeEnd: number;
updateQuery: (query: object | undefined) => void;
}
type Props = FilterBarProps & UptimeCommonProps;
const MAX_SELECTION_LENGTH = 20;
const SEARCH_THRESHOLD = 2;
export const FilterBar = ({ dateRangeEnd, dateRangeStart, updateQuery }: FilterBarProps) => (
export const FilterBar = ({ dateRangeEnd, dateRangeStart, updateQuery }: Props) => (
<Query query={getFilterBarQuery} variables={{ dateRangeStart, dateRangeEnd }}>
{({ loading, error, data }) => {
if (loading) {

View file

@ -7,7 +7,7 @@
import gql from 'graphql-tag';
export const getFilterBarQuery = gql`
query FilterBar($dateRangeStart: UnsignedInteger!, $dateRangeEnd: UnsignedInteger!) {
query FilterBar($dateRangeStart: String!, $dateRangeEnd: String!) {
filterBar: getFilterBar(dateRangeStart: $dateRangeStart, dateRangeEnd: $dateRangeEnd) {
status
port

View file

@ -7,11 +7,7 @@
import gql from 'graphql-tag';
export const createGetMonitorChartsQuery = gql`
query MonitorCharts(
$dateRangeStart: UnsignedInteger!
$dateRangeEnd: UnsignedInteger!
$monitorId: String
) {
query MonitorCharts($dateRangeStart: String!, $dateRangeEnd: String!, $monitorId: String!) {
monitorChartsData: getMonitorChartsData(
monitorId: $monitorId
dateRangeStart: $dateRangeStart

View file

@ -25,22 +25,21 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { Fragment } from 'react';
import { Query } from 'react-apollo';
import { UptimeCommonProps } from '../../../uptime_app';
import { createGetMonitorChartsQuery } from './get_monitor_charts';
interface MonitorChartsProps {
dateRangeStart: number;
dateRangeEnd: number;
monitorId: string;
autorefreshInterval: number;
autorefreshEnabled: boolean;
}
interface MonitorChartsState {
crosshairLocation: number;
}
export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorChartsState> {
constructor(props: MonitorChartsProps) {
type Props = MonitorChartsProps & UptimeCommonProps;
export class MonitorCharts extends React.Component<Props, MonitorChartsState> {
constructor(props: Props) {
super(props);
this.state = { crosshairLocation: 0 };
}
@ -50,12 +49,12 @@ export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorCh
dateRangeStart,
dateRangeEnd,
monitorId,
autorefreshEnabled,
autorefreshIsPaused,
autorefreshInterval,
} = this.props;
return (
<Query
pollInterval={autorefreshEnabled ? autorefreshInterval : undefined}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
query={createGetMonitorChartsQuery}
variables={{ dateRangeStart, dateRangeEnd, monitorId }}
>
@ -85,6 +84,7 @@ export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorCh
const downSeries: any[] = [];
const upSeries: any[] = [];
const checksSeries: any[] = [];
const maxRtt: any[] = [];
monitorChartsData.forEach(
({
maxWriteRequest,
@ -97,6 +97,13 @@ export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorCh
minDuration,
status,
}: any) => {
// We're summing these values because we need to know what the max value of the RTT
// fields are in order to provide an accurate domain size for the RTT combination series.
maxRtt.push({
x: maxWriteRequest.x,
y: maxWriteRequest.y + maxValidate.y + maxContent.y + maxResponse.y + maxTcpRtt.y,
});
// TODO: these types of computations should take place on the server and be reflected in the GQL schema
rttWriteRequestSeries.push(maxWriteRequest);
rttValidateSeries.push(maxValidate);
rttContentSeries.push(maxContent);
@ -110,6 +117,16 @@ export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorCh
}
);
// As above, we are building a domain size for the chart to use.
// Without this code the chart could render data outside of the field.
const checksDomain = upSeries.concat(downSeries).map(({ y }) => y);
const domainLimits = [Math.min(...checksDomain), Math.max(...checksDomain)];
const durationDomain = avgDurationSeries.concat(areaRttSeries);
const durationLimits = [0, Math.max(...durationDomain.map(({ y }) => y))];
// find the greatest y-value for rtt chart
const rttLimits = [0, Math.max(...maxRtt.map(({ y }) => y))];
return (
<Fragment>
<EuiFlexGroup>
@ -128,6 +145,7 @@ export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorCh
stackBy="y"
margins={{ left: 60, right: 40, top: 10, bottom: 40 }}
xType={EuiSeriesChartUtils.SCALE.TIME}
yDomain={rttLimits}
width={500}
height={200}
crosshairValue={this.state.crosshairLocation}
@ -197,6 +215,7 @@ export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorCh
width={500}
height={200}
xType={EuiSeriesChartUtils.SCALE.TIME}
yDomain={durationLimits}
crosshairValue={this.state.crosshairLocation}
onCrosshairUpdate={this.updateCrosshairLocation}
>
@ -241,6 +260,7 @@ export class MonitorCharts extends React.Component<MonitorChartsProps, MonitorCh
stackBy="y"
crosshairValue={this.state.crosshairLocation}
onCrosshairUpdate={this.updateCrosshairLocation}
yDomain={domainLimits}
>
<EuiAreaSeries
name={i18n.translate(

View file

@ -7,11 +7,7 @@
import gql from 'graphql-tag';
export const getMonitorListQuery = gql`
query MonitorList(
$dateRangeStart: UnsignedInteger!
$dateRangeEnd: UnsignedInteger!
$filters: String
) {
query MonitorList($dateRangeStart: String!, $dateRangeEnd: String!, $filters: String) {
monitorStatus: getMonitors(
dateRangeStart: $dateRangeStart
dateRangeEnd: $dateRangeEnd

View file

@ -25,16 +25,15 @@ import React, { Fragment } from 'react';
import { Query } from 'react-apollo';
import { Link } from 'react-router-dom';
import { LatestMonitorsResult } from 'x-pack/plugins/uptime/common/graphql/types';
import { UptimeCommonProps } from '../../../uptime_app';
import { getMonitorListQuery } from './get_monitor_list';
interface MonitorListProps {
autorefreshInterval: number;
autorefreshEnabled: boolean;
dateRangeStart: number;
dateRangeEnd: number;
filters?: string;
}
type Props = MonitorListProps & UptimeCommonProps;
const MONITOR_LIST_DEFAULT_PAGINATION = 10;
const monitorListColumns = [
@ -136,13 +135,13 @@ const monitorListPagination = {
export const MonitorList = ({
autorefreshInterval,
autorefreshEnabled,
autorefreshIsPaused,
dateRangeStart,
dateRangeEnd,
filters,
}: MonitorListProps) => (
}: Props) => (
<Query
pollInterval={autorefreshEnabled ? autorefreshInterval : undefined}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
query={getMonitorListQuery}
variables={{ dateRangeStart, dateRangeEnd, filters }}
>

View file

@ -7,7 +7,7 @@
import gql from 'graphql-tag';
export const createGetLatestMonitorsQuery = gql`
query GetLatestMonitorQuery($dateRangeStart: UnsignedInteger!, $dateRangeEnd: UnsignedInteger!) {
query GetLatestMonitorQuery($dateRangeStart: String!, $dateRangeEnd: String!) {
latestMonitors: getLatestMonitors(
dateRangeStart: $dateRangeStart
dateRangeEnd: $dateRangeEnd

View file

@ -7,30 +7,29 @@
// @ts-ignore No typing for EuiSuperSelect
import { EuiHealth, EuiSuperSelect } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import React, { Fragment } from 'react';
import { Query } from 'react-apollo';
import { Monitor } from '../../../../common/graphql/types';
import { UptimeCommonProps } from '../../../uptime_app';
import { createGetLatestMonitorsQuery } from './get_latest_monitors';
interface MonitorSelectProps {
dateRangeStart: number;
dateRangeEnd: number;
valueOfSelectedMonitor?: string;
autorefreshInterval: number;
autorefreshEnabled: boolean;
onChange: (path: string, state: object) => void;
}
type Props = MonitorSelectProps & UptimeCommonProps;
export const MonitorSelect = ({
dateRangeStart,
dateRangeEnd,
valueOfSelectedMonitor,
autorefreshInterval,
autorefreshEnabled,
autorefreshIsPaused,
onChange,
}: MonitorSelectProps) => (
}: Props) => (
<Query
pollInterval={autorefreshEnabled ? autorefreshInterval : undefined}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
query={createGetLatestMonitorsQuery}
variables={{ dateRangeStart, dateRangeEnd }}
>
@ -59,11 +58,18 @@ export const MonitorSelect = ({
),
}));
return (
<EuiSuperSelect
options={options}
valueOfSelected={valueOfSelectedMonitor}
onChange={(e: string) => onChange(`/monitor/${e}`, {})}
/>
<Fragment>
{options.length > 0 && (
<EuiSuperSelect
options={options}
valueOfSelected={valueOfSelectedMonitor}
onChange={(e: string) => onChange(`/monitor/${e}`, {})}
/>
)}
{options.length === 0 && (
<h4>There is no monitor data available for the selected time range</h4>
)}
</Fragment>
);
}}
</Query>

View file

@ -7,11 +7,7 @@
import gql from 'graphql-tag';
export const createGetMonitorStatusBarQuery = gql`
query MonitorStatus(
$dateRangeStart: UnsignedInteger!
$dateRangeEnd: UnsignedInteger!
$monitorId: String
) {
query MonitorStatus($dateRangeStart: String!, $dateRangeEnd: String!, $monitorId: String) {
monitorStatus: getLatestMonitors(
dateRangeStart: $dateRangeStart
dateRangeEnd: $dateRangeEnd

View file

@ -10,25 +10,24 @@ import { FormattedMessage } from '@kbn/i18n/react';
import moment from 'moment';
import React from 'react';
import { Query } from 'react-apollo';
import { UptimeCommonProps } from '../../../uptime_app';
import { createGetMonitorStatusBarQuery } from './get_monitor_status_bar';
interface MonitorStatusBarProps {
dateRangeStart: number;
dateRangeEnd: number;
monitorId: string;
autorefreshInterval: number;
autorefreshEnabled: boolean;
}
type Props = MonitorStatusBarProps & UptimeCommonProps;
export const MonitorStatusBar = ({
dateRangeStart,
dateRangeEnd,
monitorId,
autorefreshEnabled,
autorefreshIsPaused,
autorefreshInterval,
}: MonitorStatusBarProps) => (
}: Props) => (
<Query
pollInterval={autorefreshEnabled ? autorefreshInterval : undefined}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
query={createGetMonitorStatusBarQuery}
variables={{ dateRangeStart, dateRangeEnd, monitorId }}
>

View file

@ -8,8 +8,8 @@ import gql from 'graphql-tag';
export const getPingsQuery = gql`
query PingList(
$dateRangeStart: UnsignedInteger!
$dateRangeEnd: UnsignedInteger!
$dateRangeStart: String!
$dateRangeEnd: String!
$monitorId: String
$status: String
$sort: String

View file

@ -27,26 +27,25 @@ import React, { Fragment } from 'react';
import { Query } from 'react-apollo';
import { UMPingSortDirectionArg } from '../../../../common/domain_types';
import { Ping } from '../../../../common/graphql/types';
import { UptimeCommonProps } from '../../../uptime_app';
import { getPingsQuery } from './get_pings';
interface PingListProps {
monitorId?: string;
dateRangeStart: number;
dateRangeEnd: number;
autorefreshInterval: number;
autorefreshEnabled: boolean;
sort?: UMPingSortDirectionArg;
size?: number;
}
type Props = PingListProps & UptimeCommonProps;
interface PingListState {
statusOptions: EuiComboBoxOptionProps[];
selectedOption: EuiComboBoxOptionProps;
maxSearchSize: number;
}
export class Pings extends React.Component<PingListProps, PingListState> {
constructor(props: PingListProps) {
export class Pings extends React.Component<Props, PingListState> {
constructor(props: Props) {
super(props);
const statusOptions = [
@ -80,7 +79,7 @@ export class Pings extends React.Component<PingListProps, PingListState> {
monitorId,
dateRangeStart,
dateRangeEnd,
autorefreshEnabled,
autorefreshIsPaused,
autorefreshInterval,
sort,
size,
@ -88,7 +87,7 @@ export class Pings extends React.Component<PingListProps, PingListState> {
const { statusOptions, selectedOption } = this.state;
return (
<Query
pollInterval={autorefreshEnabled ? autorefreshInterval : undefined}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
variables={{
monitorId,
dateRangeStart,

View file

@ -8,10 +8,10 @@ import gql from 'graphql-tag';
export const getSnapshotQuery = gql`
query Snapshot(
$dateRangeStart: UnsignedInteger
$dateRangeEnd: UnsignedInteger
$downCount: Int
$windowSize: Int
$dateRangeStart: String!
$dateRangeEnd: String!
$downCount: Int!
$windowSize: Int!
$filters: String
) {
snapshot: getSnapshot(

View file

@ -26,26 +26,25 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import { Query } from 'react-apollo';
import { UptimeCommonProps } from '../../../uptime_app';
import { SnapshotHistogram } from '../../functional/snapshot_histogram';
import { getSnapshotQuery } from './get_snapshot';
interface SnapshotProps {
dateRangeStart: number;
dateRangeEnd: number;
autorefreshEnabled: boolean;
autorefreshInterval: number;
filters?: string;
}
type Props = SnapshotProps & UptimeCommonProps;
export const Snapshot = ({
dateRangeStart,
dateRangeEnd,
autorefreshEnabled,
autorefreshIsPaused,
autorefreshInterval,
filters,
}: SnapshotProps) => (
}: Props) => (
<Query
pollInterval={autorefreshEnabled ? autorefreshInterval : undefined}
pollInterval={autorefreshIsPaused ? undefined : autorefreshInterval}
query={getSnapshotQuery}
// TODO downCount and windowSize aren't needed for MVP
variables={{ dateRangeStart, dateRangeEnd, downCount: 1, windowSize: 1, filters }}

View file

@ -1,24 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiButtonEmpty } from '@elastic/eui';
import moment from 'moment';
import React from 'react';
interface DatePickerInputProps {
date?: Date;
onClick?: () => void;
}
export class DatePickerInput extends React.Component<DatePickerInputProps> {
public render() {
return (
<EuiButtonEmpty iconType="calendar" iconSide="left" onClick={this.props.onClick}>
{moment(this.props.date || new Date()).format('MMM D YYYY HH:mm')}
</EuiButtonEmpty>
);
}
}

View file

@ -1,139 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import {
EuiButton,
EuiButtonEmpty,
EuiDatePicker,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiPopover,
EuiTitle,
} from '@elastic/eui';
import moment, { Moment } from 'moment';
import React from 'react';
import { DatePickerInput } from './date_picker_input';
import { options } from './option_definitions';
import { DateSelection } from './types';
interface UMDateRangePickerProps {
selection: DateSelection;
updateDateRange: (
kind: 'relative' | 'absolute',
relative?: { value: number; unit: string },
absolute?: { start: Date; end: Date }
) => void;
}
interface UMDateRangePickerState {
showPopover: boolean;
}
export class UMDateRangePicker extends React.Component<
UMDateRangePickerProps,
UMDateRangePickerState
> {
constructor(props: UMDateRangePickerProps) {
super(props);
this.state = {
showPopover: false,
};
}
public render() {
const {
updateDateRange,
selection: { kind, absoluteStart, absoluteEnd, relativeSpanValue, relativeSpanUnit },
} = this.props;
// move to constant
// const formatString = 'YYYY MMM DD HH:mm:SS';
return (
<EuiPopover
id="DateRangeOptions"
button={
<EuiButton onClick={this.togglePopover}>
{kind === 'absolute'
? `${moment(absoluteStart).format('MMM-DD-YYYY HH:mm')} - ${moment(
absoluteEnd
).format('MMM-DD-YYYY HH:mm')}`
: `${relativeSpanValue}${relativeSpanUnit} - now`}
</EuiButton>
}
isOpen={this.state.showPopover}
closePopover={this.hidePopover}
>
<EuiFlexGroup direction="column">
<EuiFlexItem>
<EuiTitle size="s">
<h5>Relative</h5>
</EuiTitle>
<EuiFlexGroup>
{options.map(option => (
<EuiFlexItem key={option.id}>
<EuiButtonEmpty
onClick={() => {
const { unit, value } = option.getRange();
updateDateRange('relative', { unit, value });
}}
>
{option.title}
</EuiButtonEmpty>
</EuiFlexItem>
))}
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<EuiTitle size="s">
<h5>Absolute</h5>
</EuiTitle>
<EuiFlexGroup gutterSize="m">
<EuiFlexItem>
<EuiFormRow label="Start time">
<EuiDatePicker
customInput={<DatePickerInput date={absoluteStart} />}
// @ts-ignore multiple definitions for type Moment
maxDate={moment(absoluteEnd)}
onChange={(e: Moment | null) => {
if (e !== null) {
updateDateRange('absolute', undefined, {
start: e.toDate(),
end: absoluteEnd,
});
}
}}
selected={moment(absoluteStart)}
showTimeSelect={true}
/>
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem>
<EuiFormRow label="End time">
<EuiDatePicker
customInput={<DatePickerInput date={absoluteEnd} />}
onChange={(e: Moment | null) => {
if (e !== null) {
updateDateRange('absolute', undefined, {
start: absoluteStart,
end: e.toDate(),
});
}
}}
selected={moment(absoluteEnd)}
showTimeSelect={true}
/>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPopover>
);
}
private togglePopover = () => this.setState({ showPopover: !this.state.showPopover });
private hidePopover = () => this.setState({ showPopover: false });
}

View file

@ -1,8 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { DateSelection } from './types';
export { UMDateRangePicker } from './date_range_picker';

View file

@ -1,46 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export interface DateRangeOption {
id: string;
title: string;
getRange: () => { unit: string; value: number };
}
export const options: DateRangeOption[] = [
{
id: '24hrs',
title: 'Last 24 Hours',
getRange: () => ({
unit: 'h',
value: 24,
}),
},
{
id: '12hr',
title: 'Last 12 Hours',
getRange: () => ({
unit: 'h',
value: 12,
}),
},
{
id: '2d',
title: 'Last 2 Days',
getRange: () => ({
unit: 'd',
value: 2,
}),
},
{
id: 'lastWeek',
title: 'Past week',
getRange: () => ({
unit: 'w',
value: 1,
}),
},
];

View file

@ -1,13 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export interface DateSelection {
kind: 'relative' | 'absolute';
relativeSpanValue: number;
relativeSpanUnit: string;
absoluteStart: Date;
absoluteEnd: Date;
}

View file

@ -4,13 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import moment from 'moment';
import ReactDOM from 'react-dom';
import { unmountComponentAtNode } from 'react-dom';
import chrome from 'ui/chrome';
import { PLUGIN } from '../../../../common/constants';
import { UMBreadcrumb } from '../../../breadcrumbs';
import { UptimePersistedState } from '../../../uptime_app';
import { UptimeCommonProps } from '../../../uptime_app';
import { BootstrapUptimeApp, UMFrameworkAdapter } from '../../lib';
import { CreateGraphQLClient } from './framework_adapter_types';
@ -18,11 +17,25 @@ export class UMKibanaFrameworkAdapter implements UMFrameworkAdapter {
private uiRoutes: any;
private xsrfHeader: string;
private uriPath: string;
private defaultDateRangeStart: string;
private defaultDateRangeEnd: string;
private defaultAutorefreshInterval: number;
private defaultAutorefreshIsPaused: boolean;
constructor(uiRoutes: any) {
constructor(
uiRoutes: any,
dateRangeStart?: string,
dateRangeEnd?: string,
autorefreshInterval?: number,
autorefreshIsPaused?: boolean
) {
this.uiRoutes = uiRoutes;
this.xsrfHeader = chrome.getXsrfToken();
this.uriPath = `${chrome.getBasePath()}/api/uptime/graphql`;
this.defaultDateRangeStart = dateRangeStart || 'now-15m';
this.defaultDateRangeEnd = dateRangeEnd || 'now';
this.defaultAutorefreshInterval = autorefreshInterval || 60 * 1000;
this.defaultAutorefreshIsPaused = autorefreshIsPaused || true;
}
public render = (
@ -49,7 +62,7 @@ export class UMKibanaFrameworkAdapter implements UMFrameworkAdapter {
: basePath + PLUGIN.ROUTER_BASE_NAME;
const persistedState = this.initializePersistedState();
const {
autorefreshEnabled,
autorefreshIsPaused,
autorefreshInterval,
dateRangeStart,
dateRangeEnd,
@ -61,7 +74,7 @@ export class UMKibanaFrameworkAdapter implements UMFrameworkAdapter {
kibanaBreadcrumbs,
routerBasename,
graphQLClient,
initialAutorefreshEnabled: autorefreshEnabled,
initialAutorefreshIsPaused: autorefreshIsPaused,
initialAutorefreshInterval: autorefreshInterval,
initialDateRangeStart: dateRangeStart,
initialDateRangeEnd: dateRangeEnd,
@ -95,29 +108,40 @@ export class UMKibanaFrameworkAdapter implements UMFrameworkAdapter {
});
};
private initializePersistedState = () => {
private initializePersistedState = (): UptimeCommonProps => {
const uptimeConfigurationData = window.localStorage.getItem(PLUGIN.LOCAL_STORAGE_KEY);
const defaultState: UptimeCommonProps = {
autorefreshIsPaused: this.defaultAutorefreshIsPaused,
autorefreshInterval: this.defaultAutorefreshInterval,
dateRangeStart: this.defaultDateRangeStart,
dateRangeEnd: this.defaultDateRangeEnd,
};
try {
if (uptimeConfigurationData) {
return JSON.parse(uptimeConfigurationData) || {};
} else {
const initialState: UptimePersistedState = {
autorefreshEnabled: false,
autorefreshInterval: 5000,
dateRangeStart: moment()
.subtract(1, 'day')
.valueOf(),
dateRangeEnd: moment().valueOf(),
};
this.updatePersistedState(initialState);
return initialState;
const parsed = JSON.parse(uptimeConfigurationData) || {};
const { dateRangeStart, dateRangeEnd } = parsed;
// TODO: this is defensive code to ensure we don't encounter problems
// when encountering older versions of the localStorage values.
// The old code has never been released, so users don't need it, and this
// code should be removed eventually.
if (
(dateRangeEnd && typeof dateRangeEnd === 'number') ||
(dateRangeStart && typeof dateRangeStart === 'number')
) {
this.updatePersistedState(defaultState);
return defaultState;
}
return parsed;
}
} catch (e) {
return {};
// TODO: this should result in a redirect to error page
throw e;
}
this.updatePersistedState(defaultState);
return defaultState;
};
private updatePersistedState = (state: UptimePersistedState) => {
private updatePersistedState = (state: UptimeCommonProps) => {
window.localStorage.setItem(PLUGIN.LOCAL_STORAGE_KEY, JSON.stringify(state));
};
}

View file

@ -8,7 +8,7 @@ import { NormalizedCacheObject } from 'apollo-cache-inmemory';
import ApolloClient from 'apollo-client';
import React from 'react';
import { UMBreadcrumb } from '../breadcrumbs';
import { UptimePersistedState } from '../uptime_app';
import { UptimeAppProps } from '../uptime_app';
import { CreateGraphQLClient } from './adapters/framework/framework_adapter_types';
export interface UMFrontendLibs {
@ -17,18 +17,7 @@ export interface UMFrontendLibs {
export type UMUpdateBreadcrumbs = (breadcrumbs: UMBreadcrumb[]) => void;
export interface UptimeAppProps {
isUsingK7Design: boolean;
updateBreadcrumbs: UMUpdateBreadcrumbs;
kibanaBreadcrumbs: UMBreadcrumb[];
routerBasename: string;
graphQLClient: ApolloClient<NormalizedCacheObject>;
initialDateRangeStart?: number;
initialDateRangeEnd?: number;
initialAutorefreshInterval?: number;
initialAutorefreshEnabled?: boolean;
persistState(state: UptimePersistedState): void;
}
export type UMGraphQLClient = ApolloClient<NormalizedCacheObject>; // | OtherClientType
export type BootstrapUptimeApp = (props: UptimeAppProps) => React.ReactElement<any>;

View file

@ -21,20 +21,19 @@ import { MonitorSelect } from '../components/queries/monitor_select';
import { MonitorStatusBar } from '../components/queries/monitor_status_bar';
import { Pings } from '../components/queries/ping_list';
import { UMUpdateBreadcrumbs } from '../lib/lib';
import { UptimeCommonProps } from '../uptime_app';
interface MonitorPageProps {
updateBreadcrumbs: UMUpdateBreadcrumbs;
history: { push: any };
location: { pathname: string };
match: { params: { id: string } };
dateRangeStart: number;
dateRangeEnd: number;
autorefreshEnabled: boolean;
autorefreshInterval: number;
}
export class MonitorPage extends React.Component<MonitorPageProps> {
constructor(props: MonitorPageProps) {
type Props = MonitorPageProps & UptimeCommonProps;
export class MonitorPage extends React.Component<Props> {
constructor(props: Props) {
super(props);
}
@ -43,13 +42,7 @@ export class MonitorPage extends React.Component<MonitorPageProps> {
}
public render() {
const {
autorefreshEnabled,
autorefreshInterval,
dateRangeStart,
dateRangeEnd,
history,
} = this.props;
const { history } = this.props;
// TODO: this is a hack because the id field's characters mess up react router's
// inner params parsing, when we add a synthetic ID for monitors this problem should go away
const id = this.props.location.pathname.replace(/^(\/monitor\/)/, '');
@ -69,40 +62,15 @@ export class MonitorPage extends React.Component<MonitorPageProps> {
</span>
</EuiFlexItem>
<EuiFlexItem>
<MonitorSelect
dateRangeStart={dateRangeStart}
dateRangeEnd={dateRangeEnd}
valueOfSelectedMonitor={id}
autorefreshEnabled={autorefreshEnabled}
autorefreshInterval={autorefreshInterval}
onChange={history.push}
/>
<MonitorSelect valueOfSelectedMonitor={id} onChange={history.push} {...this.props} />
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer />
<MonitorStatusBar
dateRangeStart={dateRangeStart}
dateRangeEnd={dateRangeEnd}
monitorId={id}
autorefreshEnabled={autorefreshEnabled}
autorefreshInterval={autorefreshInterval}
/>
<MonitorStatusBar monitorId={id} {...this.props} />
<EuiSpacer />
<MonitorCharts
monitorId={id}
dateRangeStart={dateRangeStart}
dateRangeEnd={dateRangeEnd}
autorefreshEnabled={autorefreshEnabled}
autorefreshInterval={autorefreshInterval}
/>
<MonitorCharts monitorId={id} {...this.props} />
<EuiSpacer />
<Pings
dateRangeStart={this.props.dateRangeStart}
dateRangeEnd={this.props.dateRangeEnd}
monitorId={id}
autorefreshEnabled={autorefreshEnabled}
autorefreshInterval={autorefreshInterval}
/>
<Pings monitorId={id} {...this.props} />
</Fragment>
);
}

View file

@ -13,21 +13,20 @@ import { FilterBar } from '../components/queries/filter_bar';
import { MonitorList } from '../components/queries/monitor_list';
import { Snapshot } from '../components/queries/snapshot';
import { UMUpdateBreadcrumbs } from '../lib/lib';
import { UptimeCommonProps } from '../uptime_app';
interface OverviewPageProps {
autorefreshInterval: number;
autorefreshEnabled: boolean;
dateRangeStart: number;
dateRangeEnd: number;
setBreadcrumbs: UMUpdateBreadcrumbs;
}
type Props = OverviewPageProps & UptimeCommonProps;
interface OverviewPageState {
currentFilterQuery?: string;
}
export class OverviewPage extends React.Component<OverviewPageProps, OverviewPageState> {
constructor(props: OverviewPageProps) {
export class OverviewPage extends React.Component<Props, OverviewPageState> {
constructor(props: Props) {
super(props);
this.state = {
currentFilterQuery: undefined,
@ -39,41 +38,20 @@ export class OverviewPage extends React.Component<OverviewPageProps, OverviewPag
}
public render() {
const { autorefreshEnabled, autorefreshInterval, dateRangeStart, dateRangeEnd } = this.props;
return (
<Fragment>
<EmptyState
autorefreshEnabled={autorefreshEnabled}
autorefreshInterval={autorefreshInterval}
>
<EmptyState {...this.props}>
<FilterBar
dateRangeStart={dateRangeStart}
dateRangeEnd={dateRangeEnd}
{...this.props}
updateQuery={(query: object | undefined) => {
this.setState({ currentFilterQuery: query ? JSON.stringify(query) : query });
}}
/>
<Snapshot
autorefreshEnabled={autorefreshEnabled}
autorefreshInterval={autorefreshInterval}
dateRangeStart={dateRangeStart}
dateRangeEnd={dateRangeEnd}
filters={this.state.currentFilterQuery}
/>
<Snapshot filters={this.state.currentFilterQuery} {...this.props} />
<EuiSpacer size="xl" />
<MonitorList
autorefreshEnabled={autorefreshEnabled}
autorefreshInterval={autorefreshInterval}
dateRangeStart={dateRangeStart}
dateRangeEnd={dateRangeEnd}
filters={this.state.currentFilterQuery}
/>
<MonitorList filters={this.state.currentFilterQuery} {...this.props} />
<EuiSpacer />
<ErrorList
dateRangeStart={dateRangeStart}
dateRangeEnd={dateRangeEnd}
filters={this.state.currentFilterQuery}
/>
<ErrorList filters={this.state.currentFilterQuery} {...this.props} />
</EmptyState>
</Fragment>
);

View file

@ -5,12 +5,6 @@
*/
import {
EuiButton,
EuiComboBox,
EuiDatePicker,
EuiDatePickerRange,
EuiFlexGroup,
EuiFlexItem,
EuiHeader,
EuiHeaderBreadcrumbs,
// @ts-ignore missing typings for EuiHeaderLink
@ -24,36 +18,56 @@ import {
EuiHeaderSectionItem,
EuiPage,
EuiPageContent,
EuiPopover,
EuiSwitch,
// @ts-ignore missing typings for EuiSuperDatePicker
EuiSuperDatePicker,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
import moment, { Moment } from 'moment';
import React from 'react';
import { ApolloProvider } from 'react-apollo';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { overviewBreadcrumb, UMBreadcrumb } from './breadcrumbs';
import { UMUpdateBreadcrumbs, UptimeAppProps } from './lib/lib';
import { UMGraphQLClient, UMUpdateBreadcrumbs } from './lib/lib';
import { MonitorPage, OverviewPage } from './pages';
export interface UptimePersistedState {
autorefreshEnabled: boolean;
// TODO: these props are global to this app, we should put them in a context
export interface UptimeCommonProps {
autorefreshIsPaused: boolean;
autorefreshInterval: number;
dateRangeStart: number;
dateRangeEnd: number;
dateRangeStart: string;
dateRangeEnd: string;
}
export interface UptimeAppProps {
isUsingK7Design: boolean;
updateBreadcrumbs: UMUpdateBreadcrumbs;
kibanaBreadcrumbs: UMBreadcrumb[];
routerBasename: string;
graphQLClient: UMGraphQLClient;
initialDateRangeStart: string;
initialDateRangeEnd: string;
initialAutorefreshInterval: number;
initialAutorefreshIsPaused: boolean;
persistState(state: UptimeCommonProps): void;
}
interface UptimeAppState {
autorefreshIsPaused: boolean;
autorefreshInterval: number;
breadcrumbs: UMBreadcrumb[];
autorefreshEnabled: boolean;
popoverIsOpen: boolean;
// TODO: these get passed as props to most components in this plugin,
// they can probably be globalized in a context
selectedAutorefresh: any;
autorefreshOptions: any[];
dateRangeStart: number;
dateRangeEnd: number;
dateRangeStart: string;
dateRangeEnd: string;
}
// TODO: when EUI exports types for this, this should be replaced
interface SuperDateRangePickerRangeChangedEvent {
start: string;
end: string;
}
interface SuperDateRangePickerRefreshChangedEvent {
isPaused: boolean;
refreshInterval?: number;
}
class Application extends React.Component<UptimeAppProps, UptimeAppState> {
@ -65,26 +79,13 @@ class Application extends React.Component<UptimeAppProps, UptimeAppState> {
isUsingK7Design,
kibanaBreadcrumbs,
updateBreadcrumbs,
initialAutorefreshEnabled,
initialAutorefreshInterval,
initialDateRangeStart,
initialDateRangeEnd,
initialAutorefreshIsPaused: autorefreshIsPaused,
initialAutorefreshInterval: autorefreshInterval,
initialDateRangeStart: dateRangeStart,
initialDateRangeEnd: dateRangeEnd,
} = props;
let initialBreadcrumbs: UMBreadcrumb[];
const dateRangeStart =
initialDateRangeStart ||
moment()
.subtract(1, 'day')
.valueOf();
// TODO: this will cause the date range to default to being greater than "now"
// when we start using the SuperDatePicker, we'll likely revise this.
const dateRangeEnd =
initialDateRangeEnd && initialDateRangeEnd > moment().valueOf()
? initialDateRangeEnd
: moment()
.add(1, 'hours')
.valueOf();
if (isUsingK7Design) {
this.setBreadcrumbs = updateBreadcrumbs;
@ -94,25 +95,10 @@ class Application extends React.Component<UptimeAppProps, UptimeAppState> {
initialBreadcrumbs = [overviewBreadcrumb];
}
const minsToMillis = (mins: number) => mins * 60 * 1000;
const autorefreshOptions = [
{ label: '5s', value: 5000 },
{ label: '15s', value: 15000 },
{ label: '30s', value: 30000 },
{ label: '1m', value: minsToMillis(1) },
{ label: '5m', value: minsToMillis(5) },
{ label: '10m', value: minsToMillis(10) },
{ label: '30m', value: minsToMillis(30) },
];
this.state = {
autorefreshEnabled: initialAutorefreshEnabled || false,
autorefreshIsPaused,
autorefreshInterval,
breadcrumbs: initialBreadcrumbs,
popoverIsOpen: false,
autorefreshOptions,
selectedAutorefresh:
autorefreshOptions.find(opt => opt.value === initialAutorefreshInterval) ||
autorefreshOptions[0],
dateRangeStart,
dateRangeEnd,
};
@ -124,7 +110,6 @@ class Application extends React.Component<UptimeAppProps, UptimeAppState> {
public render() {
const { isUsingK7Design, routerBasename, graphQLClient } = this.props;
const dateRangeIsInvalid = () => this.state.dateRangeStart > this.state.dateRangeEnd;
return (
<I18nProvider>
<Router basename={routerBasename}>
@ -161,96 +146,41 @@ class Application extends React.Component<UptimeAppProps, UptimeAppState> {
</EuiHeaderSection>
<EuiHeaderSection side="right">
<EuiHeaderSectionItem border="none">
<div style={{ marginTop: '10px', marginLeft: '8px' }}>
<EuiDatePickerRange
startDateControl={
<EuiDatePicker
selected={moment(this.state.dateRangeStart)}
isInvalid={dateRangeIsInvalid()}
aria-label={i18n.translate('xpack.uptime.startDateRangeAriaLabel', {
defaultMessage: 'Start date',
})}
onChange={(e: Moment | null) => {
if (e && e.valueOf() < this.state.dateRangeEnd) {
this.setState({ dateRangeStart: e.valueOf() }, this.persistState);
}
}}
showTimeSelect
/>
}
endDateControl={
<EuiDatePicker
selected={moment(this.state.dateRangeEnd)}
isInvalid={dateRangeIsInvalid()}
aria-label={i18n.translate('xpack.uptime.endDateRangeAriaLabel', {
defaultMessage: 'End date',
})}
onChange={(e: Moment | null) => {
if (e && this.state.dateRangeStart < e.valueOf()) {
this.setState({ dateRangeEnd: e.valueOf() }, this.persistState);
}
}}
showTimeSelect
/>
}
<div
style={{
marginTop: '10px',
marginLeft: '16px',
marginRight: '16px',
minWidth: '600px',
}}
>
<EuiSuperDatePicker
start={this.state.dateRangeStart}
end={this.state.dateRangeEnd}
isPaused={this.state.autorefreshIsPaused}
refreshInterval={this.state.autorefreshInterval}
onTimeChange={({ start, end }: SuperDateRangePickerRangeChangedEvent) => {
this.setState(
{ dateRangeStart: start, dateRangeEnd: end },
this.persistState
);
}}
onRefreshChange={({
isPaused,
refreshInterval,
}: SuperDateRangePickerRefreshChangedEvent) => {
const autorefreshInterval =
refreshInterval === undefined
? this.state.autorefreshInterval
: refreshInterval;
this.setState(
{ autorefreshIsPaused: isPaused, autorefreshInterval },
this.persistState
);
}}
/>
</div>
</EuiHeaderSectionItem>
<EuiHeaderSectionItem border="none">
<EuiPopover
id="autorefreshPopover"
button={
<EuiButton
iconType="arrowDown"
iconSide="right"
onClick={() => this.setState({ popoverIsOpen: true })}
>
{this.state.autorefreshEnabled
? i18n.translate('xpack.uptime.autorefreshIntervalSelectedLabel', {
values: { selectedValue: this.state.selectedAutorefresh.label },
defaultMessage: 'Autorefresh every {selectedValue}',
})
: i18n.translate('xpack.uptime.autorefreshIntervalDisabledLabel', {
defaultMessage: 'Autorefresh Disabled',
})}
</EuiButton>
}
closePopover={() => this.setState({ popoverIsOpen: false })}
isOpen={this.state.popoverIsOpen}
style={{ paddingLeft: '8px', paddingTop: '10px', paddingRight: '8px' }}
>
<EuiFlexGroup direction="column">
<EuiFlexItem>
<EuiSwitch
label={i18n.translate('xpack.uptime.autoRefreshSwitchLabel', {
defaultMessage: 'Auto-refresh',
})}
checked={this.state.autorefreshEnabled}
onChange={e => {
this.setState(
{ autorefreshEnabled: e.target.checked },
this.persistState
);
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiComboBox
onChange={selectedOptions => {
this.setState(
{ selectedAutorefresh: selectedOptions[0] },
this.persistState
);
}}
options={this.state.autorefreshOptions}
isClearable={false}
singleSelection={{ asPlainText: true }}
selectedOptions={[this.state.selectedAutorefresh]}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPopover>
</EuiHeaderSectionItem>
</EuiHeaderSection>
<EuiHeaderSection side="right">
<EuiHeaderSection>
@ -281,10 +211,7 @@ class Application extends React.Component<UptimeAppProps, UptimeAppState> {
render={props => (
<OverviewPage
{...props}
autorefreshEnabled={this.state.autorefreshEnabled}
autorefreshInterval={this.state.selectedAutorefresh.value}
dateRangeStart={this.state.dateRangeStart}
dateRangeEnd={this.state.dateRangeEnd}
{...this.state}
setBreadcrumbs={this.setBreadcrumbs}
/>
)}
@ -294,11 +221,8 @@ class Application extends React.Component<UptimeAppProps, UptimeAppState> {
render={props => (
<MonitorPage
{...props}
dateRangeStart={this.state.dateRangeStart}
dateRangeEnd={this.state.dateRangeEnd}
{...this.state}
updateBreadcrumbs={this.setBreadcrumbs}
autorefreshEnabled={this.state.autorefreshEnabled}
autorefreshInterval={this.state.selectedAutorefresh.value}
/>
)}
/>
@ -312,20 +236,13 @@ class Application extends React.Component<UptimeAppProps, UptimeAppState> {
}
private persistState = (): void => {
const {
autorefreshEnabled,
selectedAutorefresh: { value },
const { autorefreshIsPaused, autorefreshInterval, dateRangeStart, dateRangeEnd } = this.state;
this.props.persistState({
autorefreshIsPaused,
autorefreshInterval,
dateRangeStart,
dateRangeEnd,
} = this.state;
if (dateRangeEnd > dateRangeStart) {
this.props.persistState({
autorefreshEnabled,
autorefreshInterval: value,
dateRangeStart,
dateRangeEnd,
});
}
});
};
}

View file

@ -6,88 +6,60 @@
import { UMGqlRange } from '../../../common/domain_types';
import { UMResolver } from '../../../common/graphql/resolver_types';
import { Ping, Snapshot } from '../../../common/graphql/types';
import {
GetErrorsListQueryArgs,
GetFilterBarQueryArgs,
GetLatestMonitorsQueryArgs,
GetMonitorChartsDataQueryArgs,
GetMonitorsQueryArgs,
GetSnapshotQueryArgs,
Ping,
Snapshot,
} from '../../../common/graphql/types';
import { UMServerLibs } from '../../lib/lib';
import { CreateUMGraphQLResolvers, UMContext } from '../types';
export type UMSnapshotResolver = UMResolver<
Snapshot | Promise<Snapshot>,
any,
GetSnapshotArgs,
GetSnapshotQueryArgs,
UMContext
>;
export type UMMonitorsResolver = UMResolver<any | Promise<any>, any, UMGqlRange, UMContext>;
interface UMLatestMonitorsArgs {
dateRangeStart: number;
dateRangeEnd: number;
monitorId?: string;
}
interface UMGetMonitorsArgs {
dateRangeStart: number;
dateRangeEnd: number;
filters: string;
}
export type UMGetMonitorsResolver = UMResolver<
any | Promise<any>,
any,
UMGetMonitorsArgs,
GetMonitorsQueryArgs,
UMContext
>;
export type UMLatestMonitorsResolver = UMResolver<
Ping[] | Promise<Ping[]>,
any,
UMLatestMonitorsArgs,
GetLatestMonitorsQueryArgs,
UMContext
>;
interface GetSnapshotArgs {
dateRangeStart: number;
dateRangeEnd: number;
downCount: number;
windowSize: number;
filters?: string;
}
interface UMMonitorChartsArgs {
dateRangeStart: number;
dateRangeEnd: number;
monitorId: string;
}
export type UMGetMonitorChartsResolver = UMResolver<
any | Promise<any>,
any,
UMMonitorChartsArgs,
GetMonitorChartsDataQueryArgs,
UMContext
>;
interface UMGetFilterBarArgs {
dateRangeStart: number;
dateRangeEnd: number;
}
export type UMGetFilterBarResolver = UMResolver<
any | Promise<any>,
any,
UMGetFilterBarArgs,
GetFilterBarQueryArgs,
UMContext
>;
interface UMGetErrorsList {
dateRangeStart: number;
dateRangeEnd: number;
filters?: string;
}
export type UMGetErrorsListResolver = UMResolver<
any | Promise<any>,
any,
UMGetErrorsList,
GetErrorsListQueryArgs,
UMContext
>;
@ -118,7 +90,8 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = (
): Promise<any> {
const { up, down, trouble } = await libs.monitors.getSnapshotCount(
req,
{ dateRangeStart, dateRangeEnd },
dateRangeStart,
dateRangeEnd,
downCount,
windowSize,
filters
@ -130,7 +103,7 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = (
// @ts-ignore TODO update typings and remove this comment
trouble,
total: up + down + trouble,
histogram: await libs.pings.getHist(req, { dateRangeStart, dateRangeEnd }, filters),
histogram: await libs.pings.getPingHistogram(req, dateRangeStart, dateRangeEnd, filters),
};
},
async getMonitorChartsData(

View file

@ -92,37 +92,29 @@ export const monitorsSchema = gql`
extend type Query {
getMonitors(
dateRangeStart: UnsignedInteger!
dateRangeEnd: UnsignedInteger!
dateRangeStart: String!
dateRangeEnd: String!
filters: String
): LatestMonitorsResult
getSnapshot(
dateRangeStart: UnsignedInteger
dateRangeEnd: UnsignedInteger
downCount: Int
windowSize: Int
dateRangeStart: String!
dateRangeEnd: String!
downCount: Int!
windowSize: Int!
filters: String
): Snapshot
getMonitorChartsData(
monitorId: String
dateRangeStart: UnsignedInteger
dateRangeEnd: UnsignedInteger
monitorId: String!
dateRangeStart: String!
dateRangeEnd: String!
): [MonitorChartEntry]
getLatestMonitors(
dateRangeStart: UnsignedInteger!
dateRangeEnd: UnsignedInteger!
monitorId: String
): [Ping!]!
getLatestMonitors(dateRangeStart: String!, dateRangeEnd: String!, monitorId: String): [Ping!]!
getFilterBar(dateRangeStart: UnsignedInteger!, dateRangeEnd: UnsignedInteger!): FilterBar
getFilterBar(dateRangeStart: String!, dateRangeEnd: String!): FilterBar
getErrorsList(
dateRangeStart: UnsignedInteger!
dateRangeEnd: UnsignedInteger!
filters: String
): [ErrorListItem]
getErrorsList(dateRangeStart: String!, dateRangeEnd: String!, filters: String): [ErrorListItem]
}
`;

View file

@ -4,26 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { UMPingSortDirectionArg } from '../../../common/domain_types';
import { UMResolver } from '../../../common/graphql/resolver_types';
import { DocCount, PingResults } from '../../../common/graphql/types';
import { AllPingsQueryArgs, DocCount, PingResults } from '../../../common/graphql/types';
import { UMServerLibs } from '../../lib/lib';
import { UMContext } from '../types';
import { CreateUMGraphQLResolvers } from '../types';
interface UMAllPingsArgs {
sort: UMPingSortDirectionArg;
size?: number;
monitorId: string;
status: string;
dateRangeStart: number;
dateRangeEnd: number;
}
export type UMAllPingsResolver = UMResolver<
PingResults | Promise<PingResults>,
any,
UMAllPingsArgs,
AllPingsQueryArgs,
UMContext
>;

View file

@ -23,9 +23,9 @@ export const pingsSchema = gql`
size: Int
monitorId: String
status: String
dateRangeStart: UnsignedInteger!
dateRangeEnd: UnsignedInteger!
): PingResults!
dateRangeStart: String!
dateRangeEnd: String!
): [Ping!]!
"Gets the number of documents in the target index"
getDocCount: DocCount!

View file

@ -4,33 +4,32 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { UMGqlRange } from '../../../../common/domain_types';
export interface UMMonitorsAdapter {
getMonitorChartsData(
request: any,
monitorId: string,
dateRangeStart: number,
dateRangeEnd: number
dateRangeStart: string,
dateRangeEnd: string
): Promise<any>;
getLatestMonitors(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<any>;
getSnapshotCount(
request: any,
range: UMGqlRange,
dateRangeStart: string,
dateRangeEnd: string,
downCount: number,
windowSize: number,
filters?: string
filters?: string | null
): Promise<any>;
getFilterBar(request: any, dateRangeStart: number, dateRangeEnd: number): Promise<any>;
getFilterBar(request: any, dateRangeStart: string, dateRangeEnd: string): Promise<any>;
getErrorsList(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters?: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<any>;
}

View file

@ -6,7 +6,6 @@
import { get, set } from 'lodash';
import { INDEX_NAMES } from '../../../../common/constants';
import { UMGqlRange } from '../../../../common/domain_types';
import { ErrorListItem } from '../../../../common/graphql/types';
import { DatabaseAdapter } from '../database';
import { UMMonitorsAdapter } from './adapter_types';
@ -37,7 +36,11 @@ const formatStatusBuckets = (time: any, buckets: any, docCount: any) => {
};
};
const getFilteredQuery = (dateRangeStart: number, dateRangeEnd: number, filters?: string) => {
const getFilteredQuery = (
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
) => {
let filtersObj;
// TODO: handle bad JSON gracefully
filtersObj = filters ? JSON.parse(filters) : undefined;
@ -68,8 +71,8 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
public async getMonitorChartsData(
request: any,
monitorId: string,
dateRangeStart: number,
dateRangeEnd: number
dateRangeStart: string,
dateRangeEnd: string
): Promise<any> {
const query = {
bool: {
@ -141,12 +144,12 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
public async getSnapshotCount(
request: any,
range: UMGqlRange,
dateRangeStart: string,
dateRangeEnd: string,
downCount: number,
windowSize: number,
filters: string = ''
filters?: string | null
): Promise<any> {
const { dateRangeStart, dateRangeEnd } = range;
const params = {
index: INDEX_NAMES.HEARTBEAT,
body: {
@ -225,9 +228,9 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
public async getLatestMonitors(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<any> {
const params = {
index: INDEX_NAMES.HEARTBEAT,
@ -315,8 +318,8 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
public async getFilterBar(
request: any,
dateRangeStart: number,
dateRangeEnd: number
dateRangeStart: string,
dateRangeEnd: string
): Promise<any> {
const params = {
index: INDEX_NAMES.HEARTBEAT,
@ -369,9 +372,9 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
public async getErrorsList(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters?: string | undefined
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<ErrorListItem[]> {
const statusDown = {
term: {

View file

@ -4,8 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import moment from 'moment';
import { UMGqlRange } from '../../../../common/domain_types';
import { Ping } from '../../../../common/graphql/types';
import { UMMonitorsAdapter } from './adapter_types';
@ -18,29 +16,32 @@ export class UMMemoryMonitorsAdapter implements UMMonitorsAdapter {
public async getLatestMonitors(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<any> {
return this.monitorsDB.filter(ping => {
const timestamp = moment(ping.timestamp).valueOf();
return dateRangeStart <= timestamp && timestamp <= dateRangeEnd;
// const timestamp = moment(ping.timestamp).valueOf();
throw new Error('Method not implemented.');
// return dateRangeStart <= timestamp && timestamp <= dateRangeEnd;
});
}
public async getMonitorChartsData(
req: any,
monitorId: string,
dateRangeStart: number,
dateRangeEnd: number
dateRangeStart: string,
dateRangeEnd: string
): Promise<any> {
throw new Error('Method not implemented.');
}
public async getSnapshotCount(
request: any,
range: UMGqlRange,
dateRangeStart: string,
dateRangeEnd: string,
downCount: number,
windowSize: number
windowSize: number,
filters?: string | null
): Promise<any> {
throw new Error('Method not implemented.');
}
@ -50,9 +51,9 @@ export class UMMemoryMonitorsAdapter implements UMMonitorsAdapter {
public async getErrorsList(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters?: string | undefined
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<any> {
throw new Error('Method not implemented.');
}

View file

@ -70,7 +70,7 @@ describe('ElasticsearchPingsAdapter class', () => {
body: {
query: {
bool: {
filter: [{ range: { '@timestamp': { gte: 100, lte: 200 } } }],
filter: [{ range: { '@timestamp': { gte: 'now-1h', lte: 'now' } } }],
must: [],
},
},
@ -81,7 +81,15 @@ describe('ElasticsearchPingsAdapter class', () => {
});
it('returns data in the appropriate shape', async () => {
const result = await adapter.getAll(serverRequest, 100, 200, undefined, undefined, 'asc', 12);
const result = await adapter.getAll(
serverRequest,
'now-1h',
'now',
undefined,
undefined,
'asc',
12
);
const count = 3;
expect(result.total).toBe(count);
@ -96,7 +104,7 @@ describe('ElasticsearchPingsAdapter class', () => {
it('creates appropriate sort and size parameters', async () => {
database.search = getAllSearchMock;
await adapter.getAll(serverRequest, 100, 200, undefined, undefined, 'asc', 12);
await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, undefined, 'asc', 12);
expect(database.search).toHaveBeenCalledTimes(1);
expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams);
@ -104,14 +112,14 @@ describe('ElasticsearchPingsAdapter class', () => {
it('omits the sort param when no sort passed', async () => {
database.search = getAllSearchMock;
await adapter.getAll(serverRequest, 100, 200, undefined, undefined, undefined, 12);
await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, undefined, undefined, 12);
delete expectedGetAllParams.body.sort;
expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams);
});
it('omits the size param when no size passed', async () => {
database.search = getAllSearchMock;
await adapter.getAll(serverRequest, 100, 200, undefined, undefined, 'desc');
await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, undefined, 'desc');
delete expectedGetAllParams.body.size;
set(expectedGetAllParams, 'body.sort[0].@timestamp.order', 'desc');
expect(database.search).toHaveBeenCalledWith(serverRequest, expectedGetAllParams);
@ -119,7 +127,7 @@ describe('ElasticsearchPingsAdapter class', () => {
it('adds a filter for monitor ID', async () => {
database.search = getAllSearchMock;
await adapter.getAll(serverRequest, 100, 200, 'testmonitorid');
await adapter.getAll(serverRequest, 'now-1h', 'now', 'testmonitorid');
delete expectedGetAllParams.body.size;
delete expectedGetAllParams.body.sort;
expectedGetAllParams.body.query.bool.must.push({ term: { 'monitor.id': 'testmonitorid' } });
@ -128,7 +136,7 @@ describe('ElasticsearchPingsAdapter class', () => {
it('adds a filter for monitor status', async () => {
database.search = getAllSearchMock;
await adapter.getAll(serverRequest, 100, 200, undefined, 'down');
await adapter.getAll(serverRequest, 'now-1h', 'now', undefined, 'down');
delete expectedGetAllParams.body.size;
delete expectedGetAllParams.body.sort;
expectedGetAllParams.body.query.bool.must.push({ term: { 'monitor.status': 'down' } });
@ -150,8 +158,8 @@ describe('ElasticsearchPingsAdapter class', () => {
{
range: {
'@timestamp': {
gte: 100,
lte: 200,
gte: 'now-1h',
lte: 'now',
},
},
},
@ -207,7 +215,12 @@ describe('ElasticsearchPingsAdapter class', () => {
it('returns data in expected shape', async () => {
database.search = getLatestSearchMock;
const result = await adapter.getLatestMonitorDocs(serverRequest, 100, 200, 'testmonitor');
const result = await adapter.getLatestMonitorDocs(
serverRequest,
'now-1h',
'now',
'testmonitor'
);
expect(result).toHaveLength(1);
expect(result[0].timestamp).toBe(123456);
expect(result[0].monitor).not.toBeFalsy();

View file

@ -4,31 +4,31 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { UMGqlRange, UMPingSortDirectionArg } from '../../../../common/domain_types';
import { DocCount, HistogramSeries, Ping, PingResults } from '../../../../common/graphql/types';
export interface UMPingsAdapter {
getAll(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string,
status?: string,
sort?: UMPingSortDirectionArg,
size?: number
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null,
status?: string | null,
sort?: string | null,
size?: number | null
): Promise<PingResults>;
getLatestMonitorDocs(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null
): Promise<Ping[]>;
getPingHistogram(
request: any,
range: UMGqlRange,
filters?: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<HistogramSeries[] | null>;
getDocCount(request: any): Promise<DocCount>;

View file

@ -6,12 +6,15 @@
import { get } from 'lodash';
import { INDEX_NAMES } from '../../../../common/constants';
import { UMGqlRange, UMPingSortDirectionArg } from '../../../../common/domain_types';
import { DocCount, HistogramSeries, Ping, PingResults } from '../../../../common/graphql/types';
import { DatabaseAdapter } from '../database';
import { UMPingsAdapter } from './adapter_types';
const getFilteredQuery = (dateRangeStart: number, dateRangeEnd: number, filters?: string) => {
const getFilteredQuery = (
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
) => {
let filtersObj;
// TODO: handle bad JSON gracefully
filtersObj = filters ? JSON.parse(filters) : undefined;
@ -43,12 +46,12 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
public async getAll(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string,
status?: string,
sort?: UMPingSortDirectionArg,
size?: number
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null,
status?: string | null,
sort?: string | null,
size?: number | null
): Promise<PingResults> {
const sortParam = sort ? { sort: [{ '@timestamp': { order: sort } }] } : undefined;
const sizeParam = size ? { size } : undefined;
@ -90,9 +93,9 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
public async getLatestMonitorDocs(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null
): Promise<Ping[]> {
const must: any[] = [];
if (monitorId) {
@ -147,10 +150,10 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
public async getPingHistogram(
request: any,
range: UMGqlRange,
filters?: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<HistogramSeries[] | null> {
const { dateRangeStart, dateRangeEnd } = range;
const params = {
index: INDEX_NAMES.HEARTBEAT,
body: {

View file

@ -5,11 +5,10 @@
*/
import { take } from 'lodash';
import { UMPingSortDirectionArg } from '../../../../common/domain_types';
import { DocCount, HistogramSeries, Ping, PingResults } from '../../../../common/graphql/types';
import { UMPingsAdapter } from './adapter_types';
const sortPings = (sort: UMPingSortDirectionArg) =>
const sortPings = (sort: string) =>
sort === 'asc'
? (a: Ping, b: Ping) => (Date.parse(a.timestamp) > Date.parse(b.timestamp) ? 1 : 0)
: (a: Ping, b: Ping) => (Date.parse(a.timestamp) > Date.parse(b.timestamp) ? 0 : 1);
@ -23,12 +22,12 @@ export class MemoryPingsAdapter implements UMPingsAdapter {
public async getAll(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string,
status?: string,
sort?: UMPingSortDirectionArg,
size?: number
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null,
status?: string | null,
sort?: string | null,
size?: number | null
): Promise<PingResults> {
let pings = this.pingsDB;
if (monitorId) {
@ -42,21 +41,28 @@ export class MemoryPingsAdapter implements UMPingsAdapter {
};
}
// TODO implement
public async getLatestMonitorDocs(
// TODO: implement
public getLatestMonitorDocs(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null
): Promise<Ping[]> {
throw new Error('Method not implemented.');
}
// TODO implement
public async getPingHistogram(request: any): Promise<HistogramSeries[] | null> {
// TODO: implement
public getPingHistogram(
request: any,
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null | undefined
): Promise<HistogramSeries[] | null> {
throw new Error('Method not implemented.');
}
public async getDocCount(request: any): Promise<DocCount> {
// TODO: implement
public getDocCount(request: any): Promise<DocCount> {
throw new Error('Method not implemented.');
}
}

View file

@ -45,8 +45,8 @@ describe('Pings domain lib', () => {
const request: any = {};
const apiResponse = await libs.pings.getAll(
request,
100,
200,
'now-1h',
'now',
undefined,
undefined,
'asc',
@ -61,8 +61,8 @@ describe('Pings domain lib', () => {
it('should sort desc and take a range', async () => {
const apiResponse = await libs.pings.getAll(
undefined,
100,
200,
'now-1h',
'now',
undefined,
undefined,
'desc',
@ -77,8 +77,8 @@ describe('Pings domain lib', () => {
it('should take range without sort', async () => {
const apiResponse = await libs.pings.getAll(
undefined,
100,
200,
'now-1h',
'now',
undefined,
undefined,
undefined,
@ -93,8 +93,8 @@ describe('Pings domain lib', () => {
it('should sort without range', async () => {
const apiResponse = await libs.pings.getAll(
undefined,
100,
200,
'now-1h',
'now',
undefined,
undefined,
'desc',
@ -110,8 +110,8 @@ describe('Pings domain lib', () => {
it('should return unsorted, with default size of 10', async () => {
const apiResponse = await libs.pings.getAll(
undefined,
100,
200,
'now-1h',
'now',
undefined,
undefined,
undefined,

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { UMGqlRange } from '../../../common/domain_types';
import { UMMonitorsAdapter } from '../adapters/monitors';
export class UMMonitorsDomain {
@ -15,44 +14,52 @@ export class UMMonitorsDomain {
public async getMonitorChartsData(
request: any,
monitorId: string,
dateRangeStart: number,
dateRangeEnd: number
dateRangeStart: string,
dateRangeEnd: string
): Promise<any> {
return this.adapter.getMonitorChartsData(request, monitorId, dateRangeStart, dateRangeEnd);
}
public async getMonitors(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<any> {
return this.adapter.getLatestMonitors(request, dateRangeStart, dateRangeEnd, filters);
}
public async getSnapshotCount(
request: any,
range: UMGqlRange,
dateRangeStart: string,
dateRangeEnd: string,
downCount: number,
windowSize: number,
filters?: string
filters?: string | null
): Promise<any> {
return this.adapter.getSnapshotCount(request, range, downCount, windowSize, filters);
return this.adapter.getSnapshotCount(
request,
dateRangeStart,
dateRangeEnd,
downCount,
windowSize,
filters
);
}
public async getFilterBar(
request: any,
dateRangeStart: number,
dateRangeEnd: number
dateRangeStart: string,
dateRangeEnd: string
): Promise<any> {
return this.adapter.getFilterBar(request, dateRangeStart, dateRangeEnd);
}
public async getErrorsList(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
filters?: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<any> {
return this.adapter.getErrorsList(request, dateRangeStart, dateRangeEnd, filters);
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { UMGqlRange, UMPingSortDirectionArg } from '../../../common/domain_types';
import { DocCount, HistogramSeries, Ping, PingResults } from '../../../common/graphql/types';
import { UMPingsAdapter } from '../adapters/pings';
@ -15,12 +14,12 @@ export class UMPingsDomain {
public async getAll(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string,
status?: string,
sort?: UMPingSortDirectionArg,
size?: number
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null,
status?: string | null,
sort?: string | null,
size?: number | null
): Promise<PingResults> {
return this.adapter.getAll(
request,
@ -35,19 +34,20 @@ export class UMPingsDomain {
public async getLatestMonitorDocs(
request: any,
dateRangeStart: number,
dateRangeEnd: number,
monitorId?: string
dateRangeStart: string,
dateRangeEnd: string,
monitorId?: string | null
): Promise<Ping[]> {
return this.adapter.getLatestMonitorDocs(request, dateRangeStart, dateRangeEnd, monitorId);
}
public async getHist(
public async getPingHistogram(
request: any,
range: UMGqlRange,
filters?: string
dateRangeStart: string,
dateRangeEnd: string,
filters?: string | null
): Promise<HistogramSeries[] | null> {
return this.adapter.getPingHistogram(request, range, filters);
return this.adapter.getPingHistogram(request, dateRangeStart, dateRangeEnd, filters);
}
public async getDocCount(request: any): Promise<DocCount> {