mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* 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:
parent
f4f956e3b2
commit
9990165366
45 changed files with 3179 additions and 853 deletions
2650
common/graphql/introspection.json
Normal file
2650
common/graphql/introspection.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -5,6 +5,6 @@
|
|||
*/
|
||||
|
||||
export interface UMGqlRange {
|
||||
dateRangeStart: number;
|
||||
dateRangeEnd: number;
|
||||
dateRangeStart: string;
|
||||
dateRangeEnd: string;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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', {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }}
|
||||
>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }}
|
||||
>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 }}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 });
|
||||
}
|
|
@ -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';
|
|
@ -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,
|
||||
}),
|
||||
},
|
||||
];
|
|
@ -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;
|
||||
}
|
|
@ -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));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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>;
|
||||
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -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
|
||||
>;
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue