mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[APM] Upgrade to react-redux-request (#19338)
This commit is contained in:
parent
d649f02c07
commit
66739ffdd9
39 changed files with 170 additions and 318 deletions
|
@ -138,6 +138,7 @@
|
|||
"react-markdown-renderer": "^1.4.0",
|
||||
"react-portal": "^3.2.0",
|
||||
"react-redux": "^5.0.5",
|
||||
"react-redux-request": "^1.5.5",
|
||||
"react-router-breadcrumbs-hoc": "1.1.2",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-select": "^1.2.1",
|
||||
|
|
|
@ -27,8 +27,8 @@ import {
|
|||
ERROR_EXC_MESSAGE,
|
||||
ERROR_EXC_HANDLED
|
||||
} from '../../../../common/constants';
|
||||
import { ErrorDistributionRequest } from '../../../store/reduxRequest/errorDistribution';
|
||||
import { ErrorGroupDetailsRequest } from '../../../store/reduxRequest/errorGroup';
|
||||
import { ErrorDistributionRequest } from '../../../store/reactReduxRequest/errorDistribution';
|
||||
import { ErrorGroupDetailsRequest } from '../../../store/reactReduxRequest/errorGroup';
|
||||
|
||||
const Titles = styled.div`
|
||||
margin-bottom: ${px(units.plus)};
|
||||
|
|
|
@ -73,13 +73,13 @@ function ListItem({ error, serviceName }) {
|
|||
return (
|
||||
<KuiTableRow>
|
||||
<GroupIdCell>
|
||||
<GroupIdLink path={`${serviceName}/errors/${groupId}`}>
|
||||
<GroupIdLink path={`/${serviceName}/errors/${groupId}`}>
|
||||
{groupId.slice(0, 5) || 'N/A'}
|
||||
</GroupIdLink>
|
||||
</GroupIdCell>
|
||||
<MessageAndCulpritCell>
|
||||
<TooltipOverlay content={message || 'N/A'}>
|
||||
<MessageLink path={`${serviceName}/errors/${groupId}`}>
|
||||
<MessageLink path={`/${serviceName}/errors/${groupId}`}>
|
||||
{message || 'N/A'}
|
||||
</MessageLink>
|
||||
</TooltipOverlay>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import ErrorGroupOverview from './view';
|
||||
import { getUrlParams } from '../../../store/urlParams';
|
||||
import { getLicense } from '../../../store/reduxRequest/license';
|
||||
import { getLicense } from '../../../store/reactReduxRequest/license';
|
||||
|
||||
function mapStateToProps(state = {}) {
|
||||
return {
|
||||
|
|
|
@ -11,7 +11,7 @@ import TabNavigation from '../../shared/TabNavigation';
|
|||
import List from './List';
|
||||
import WatcherFlyout from './Watcher/WatcherFlyOut';
|
||||
import OpenWatcherDialogButton from './Watcher/OpenWatcherDialogButton';
|
||||
import { ErrorGroupDetailsRequest } from '../../../store/reduxRequest/errorGroupList';
|
||||
import { ErrorGroupDetailsRequest } from '../../../store/reactReduxRequest/errorGroupList';
|
||||
|
||||
class ErrorGroupOverview extends Component {
|
||||
state = {
|
||||
|
|
|
@ -11,7 +11,7 @@ import { STATUS } from '../../../../constants/index';
|
|||
|
||||
function getIsLoading(state) {
|
||||
return some(
|
||||
state.reduxRequest,
|
||||
state.reactReduxRequest,
|
||||
subState => get(subState, 'status') === STATUS.LOADING
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { STATUS } from '../../../../constants/index';
|
||||
import { LicenceRequest } from '../../../../store/reduxRequest/license';
|
||||
import { LicenceRequest } from '../../../../store/reactReduxRequest/license';
|
||||
|
||||
function LicenseChecker() {
|
||||
return (
|
||||
|
|
|
@ -52,7 +52,7 @@ function ListItem({ service }) {
|
|||
<KuiTableRow>
|
||||
<ServiceNameCell>
|
||||
<TooltipOverlay content={formatString(serviceName)}>
|
||||
<AppLink path={`${serviceName}/transactions`}>
|
||||
<AppLink path={`/${serviceName}/transactions`}>
|
||||
{formatString(serviceName)}
|
||||
</AppLink>
|
||||
</TooltipOverlay>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { connect } from 'react-redux';
|
||||
import ServiceOverview from './view';
|
||||
import { getServiceList } from '../../../store/reduxRequest/serviceList';
|
||||
import { getServiceList } from '../../../store/reactReduxRequest/serviceList';
|
||||
import { getUrlParams } from '../../../store/urlParams';
|
||||
import sorting, { changeServiceSorting } from '../../../store/sorting';
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { EuiButton } from '@elastic/eui';
|
|||
import List from './List';
|
||||
import { HeaderContainer } from '../../shared/UIComponents';
|
||||
|
||||
import { ServiceListRequest } from '../../../store/reduxRequest/serviceList';
|
||||
import { ServiceListRequest } from '../../../store/reactReduxRequest/serviceList';
|
||||
|
||||
class ServiceOverview extends Component {
|
||||
state = {
|
||||
|
|
|
@ -17,7 +17,7 @@ import Timeline from '../../../../shared/charts/Timeline';
|
|||
import EmptyMessage from '../../../../shared/EmptyMessage';
|
||||
import { getFeatureDocs } from '../../../../../utils/documentation';
|
||||
import { ExternalLink } from '../../../../../utils/url';
|
||||
import { SpansRequest } from '../../../../../store/reduxRequest/spans';
|
||||
import { SpansRequest } from '../../../../../store/reactReduxRequest/spans';
|
||||
|
||||
const Container = styled.div`
|
||||
transition: 0.1s padding ease;
|
||||
|
|
|
@ -8,10 +8,10 @@ import React from 'react';
|
|||
import { HeaderLarge } from '../../shared/UIComponents';
|
||||
import Transaction from './Transaction';
|
||||
import Distribution from './Distribution';
|
||||
import { DetailsChartsRequest } from '../../../store/reduxRequest/detailsCharts';
|
||||
import { DetailsChartsRequest } from '../../../store/reactReduxRequest/detailsCharts';
|
||||
import Charts from '../../shared/charts/TransactionCharts';
|
||||
import { TransactionDistributionRequest } from '../../../store/reduxRequest/transactionDistribution';
|
||||
import { TransactionDetailsRequest } from '../../../store/reduxRequest/transactionDetails';
|
||||
import { TransactionDistributionRequest } from '../../../store/reactReduxRequest/transactionDistribution';
|
||||
import { TransactionDetailsRequest } from '../../../store/reactReduxRequest/transactionDetails';
|
||||
|
||||
function TransactionDetails({ urlParams }) {
|
||||
return (
|
||||
|
|
|
@ -86,7 +86,7 @@ function TransactionListItem({ serviceName, transaction, type, impact }) {
|
|||
<KuiTableRow>
|
||||
<TransactionNameCell>
|
||||
<TooltipOverlay content={transactionName || 'N/A'}>
|
||||
<TransactionNameLink path={transactionUrl}>
|
||||
<TransactionNameLink path={`/${transactionUrl}`}>
|
||||
{transactionName || 'N/A'}
|
||||
</TransactionNameLink>
|
||||
</TooltipOverlay>
|
||||
|
|
|
@ -10,9 +10,9 @@ import { HeaderLarge, HeaderMedium } from '../../shared/UIComponents';
|
|||
import TabNavigation from '../../shared/TabNavigation';
|
||||
import Charts from '../../shared/charts/TransactionCharts';
|
||||
import List from './List';
|
||||
import { OverviewChartsRequest } from '../../../store/reduxRequest/overviewCharts';
|
||||
import { TransactionListRequest } from '../../../store/reduxRequest/transactionList';
|
||||
import { ServiceDetailsRequest } from '../../../store/reduxRequest/serviceDetails';
|
||||
import { OverviewChartsRequest } from '../../../store/reactReduxRequest/overviewCharts';
|
||||
import { TransactionListRequest } from '../../../store/reactReduxRequest/transactionList';
|
||||
import { ServiceDetailsRequest } from '../../../store/reactReduxRequest/serviceDetails';
|
||||
|
||||
function ServiceDetailsAndTransactionList({ urlParams, render }) {
|
||||
return (
|
||||
|
|
|
@ -1,51 +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 PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { ReduxRequestView } from './view';
|
||||
import hash from 'object-hash/index';
|
||||
export { reduxRequestReducer } from './reducer';
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const { args, id, selector } = ownProps;
|
||||
const hashedArgs = hash(args);
|
||||
let result;
|
||||
try {
|
||||
result = selector(state, { id });
|
||||
} catch (e) {
|
||||
console.error(`The selector for "ReduxRequest#${id}" threw an error:\n`, e);
|
||||
return {
|
||||
hashedArgs,
|
||||
hasError: true
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
prevHashedArgs: result.hashedArgs,
|
||||
hashedArgs,
|
||||
result
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
dispatch
|
||||
});
|
||||
|
||||
export const ReduxRequest = connect(mapStateToProps, mapDispatchToProps)(
|
||||
ReduxRequestView
|
||||
);
|
||||
|
||||
ReduxRequest.propTypes = {
|
||||
args: PropTypes.array,
|
||||
id: PropTypes.string.isRequired,
|
||||
selector: PropTypes.func
|
||||
};
|
||||
|
||||
ReduxRequest.defaultProps = {
|
||||
args: [],
|
||||
selector: (state, props) => state.reduxRequest[props.id] || {}
|
||||
};
|
|
@ -1,51 +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 { get } from 'lodash';
|
||||
|
||||
export const ACTION_TYPES = {
|
||||
LOADING: 'REDUX_REQUEST_LOADING',
|
||||
SUCCESS: 'REDUX_REQUEST_SUCCESS',
|
||||
FAILURE: 'REDUX_REQUEST_FAILURE'
|
||||
};
|
||||
|
||||
export const STATUS = {
|
||||
LOADING: 'LOADING',
|
||||
SUCCESS: 'SUCCESS',
|
||||
FAILURE: 'FAILURE'
|
||||
};
|
||||
|
||||
function getStatus(type) {
|
||||
switch (type) {
|
||||
case ACTION_TYPES.LOADING:
|
||||
return STATUS.LOADING;
|
||||
case ACTION_TYPES.SUCCESS:
|
||||
return STATUS.SUCCESS;
|
||||
case ACTION_TYPES.FAILURE:
|
||||
return STATUS.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
export function reduxRequestReducer(state = {}, action) {
|
||||
switch (action.type) {
|
||||
case ACTION_TYPES.LOADING:
|
||||
case ACTION_TYPES.SUCCESS:
|
||||
case ACTION_TYPES.FAILURE: {
|
||||
const { id, data, error, hashedArgs } = action;
|
||||
return {
|
||||
...state,
|
||||
[id]: {
|
||||
status: getStatus(action.type),
|
||||
data: data || get(state[id], 'data'),
|
||||
error: error || get(state[id], 'error'),
|
||||
hashedArgs
|
||||
}
|
||||
};
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -1,116 +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 React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import _ from 'lodash';
|
||||
import { ACTION_TYPES } from './reducer';
|
||||
|
||||
async function maybeFetchData(
|
||||
{
|
||||
args,
|
||||
dispatch,
|
||||
hasError,
|
||||
fn,
|
||||
hashedArgs,
|
||||
id,
|
||||
prevHashedArgs,
|
||||
shouldInvoke
|
||||
},
|
||||
ctx = {}
|
||||
) {
|
||||
const shouldFetchData =
|
||||
shouldInvoke && prevHashedArgs !== hashedArgs && !hasError;
|
||||
|
||||
if (!shouldFetchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
id,
|
||||
hashedArgs,
|
||||
type: ACTION_TYPES.LOADING
|
||||
});
|
||||
const fetchId = (ctx.fetchId = _.uniqueId());
|
||||
try {
|
||||
const data = await fn(...args);
|
||||
if (fetchId === ctx.fetchId) {
|
||||
dispatch({
|
||||
data,
|
||||
hashedArgs,
|
||||
id,
|
||||
type: ACTION_TYPES.SUCCESS
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (fetchId === ctx.fetchId) {
|
||||
console.error(error);
|
||||
dispatch({
|
||||
error,
|
||||
hashedArgs,
|
||||
id,
|
||||
type: ACTION_TYPES.FAILURE
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ReduxRequestView extends React.Component {
|
||||
componentWillMount() {
|
||||
maybeFetchData(this.props, this);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
maybeFetchData(nextProps, this);
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return this.props.result !== nextProps.result;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.fetchId = null;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.hasError) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { status, data, error } = this.props.result;
|
||||
try {
|
||||
return this.props.render({ status, data, error });
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`The render method of "ReduxRequest#${
|
||||
this.props.id
|
||||
}" threw an error:\n`,
|
||||
e
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReduxRequestView.propTypes = {
|
||||
args: PropTypes.array,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
fn: PropTypes.func.isRequired,
|
||||
hasError: PropTypes.bool,
|
||||
hashedArgs: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
prevHashedArgs: PropTypes.string,
|
||||
render: PropTypes.func,
|
||||
result: PropTypes.object,
|
||||
shouldInvoke: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
ReduxRequestView.defaultProps = {
|
||||
args: [],
|
||||
hasError: false,
|
||||
render: () => {},
|
||||
result: {},
|
||||
shouldInvoke: true
|
||||
};
|
|
@ -19,7 +19,7 @@ import {
|
|||
import { isEmpty } from 'lodash';
|
||||
|
||||
import TooltipOverlay from '../../shared/TooltipOverlay';
|
||||
import { ServiceDetailsRequest } from '../../../store/reduxRequest/serviceDetails';
|
||||
import { ServiceDetailsRequest } from '../../../store/reactReduxRequest/serviceDetails';
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
|
@ -87,7 +87,7 @@ function TabNavigation({ urlParams, location }) {
|
|||
key={type}
|
||||
>
|
||||
<NavLink
|
||||
path={`${serviceName}/transactions/${encodeURIComponent(
|
||||
path={`/${serviceName}/transactions/${encodeURIComponent(
|
||||
type
|
||||
)}`}
|
||||
selected={transactionType === type && !errorsSelected}
|
||||
|
@ -101,7 +101,7 @@ function TabNavigation({ urlParams, location }) {
|
|||
/>
|
||||
|
||||
<Divider />
|
||||
<TabLink path={`${serviceName}/errors`} selected={errorsSelected}>
|
||||
<TabLink path={`/${serviceName}/errors`} selected={errorsSelected}>
|
||||
Errors
|
||||
</TabLink>
|
||||
</Container>
|
||||
|
|
|
@ -10,7 +10,7 @@ describe('root reducer', () => {
|
|||
it('should return the initial state', () => {
|
||||
expect(reducer(undefined, {})).toEqual({
|
||||
location: { hash: '', pathname: '', search: '' },
|
||||
reduxRequest: {},
|
||||
reactReduxRequest: {},
|
||||
sorting: {
|
||||
service: { descending: false, key: 'serviceName' },
|
||||
transaction: { descending: true, key: 'impact' }
|
||||
|
|
|
@ -12,13 +12,13 @@ import { mountWithStore } from '../../../utils/testHelpers';
|
|||
describe('serviceList', () => {
|
||||
describe('getServiceList', () => {
|
||||
it('should return default value when empty', () => {
|
||||
const state = { reduxRequest: {}, sorting: { service: {} } };
|
||||
const state = { reactReduxRequest: {}, sorting: { service: {} } };
|
||||
expect(getServiceList(state)).toEqual({ data: [] });
|
||||
});
|
||||
|
||||
it('should return serviceList when not empty', () => {
|
||||
const state = {
|
||||
reduxRequest: { serviceList: { data: [{ foo: 'bar' }] } },
|
||||
reactReduxRequest: { serviceList: { data: [{ foo: 'bar' }] } },
|
||||
sorting: { service: {} }
|
||||
};
|
||||
expect(getServiceList(state)).toEqual({ data: [{ foo: 'bar' }] });
|
||||
|
@ -32,7 +32,7 @@ describe('serviceList', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
const state = {
|
||||
reduxRequest: {
|
||||
reactReduxRequest: {
|
||||
serviceList: { status: 'my-status', data: [{ foo: 'bar' }] }
|
||||
},
|
||||
sorting: { service: {} }
|
|
@ -9,7 +9,7 @@ import { createSelector } from 'reselect';
|
|||
import { getCharts } from '../selectors/chartSelectors';
|
||||
import { getUrlParams } from '../urlParams';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadCharts } from '../../services/rest';
|
||||
|
||||
const ID = 'detailsCharts';
|
||||
|
@ -23,7 +23,7 @@ const INITIAL_DATA = {
|
|||
|
||||
export const getDetailsCharts = createSelector(
|
||||
getUrlParams,
|
||||
state => withInitialData(state.reduxRequest[ID], INITIAL_DATA),
|
||||
state => withInitialData(state.reactReduxRequest[ID], INITIAL_DATA),
|
||||
getCharts
|
||||
);
|
||||
|
||||
|
@ -37,13 +37,14 @@ export function DetailsChartsRequest({ urlParams, render }) {
|
|||
kuery
|
||||
} = urlParams;
|
||||
|
||||
if (!(serviceName && start && end && transactionType && transactionName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
fn={loadCharts}
|
||||
shouldInvoke={Boolean(
|
||||
serviceName && start && end && transactionType && transactionName
|
||||
)}
|
||||
args={[
|
||||
{ serviceName, start, end, transactionType, transactionName, kuery }
|
||||
]}
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadErrorDistribution } from '../../services/rest';
|
||||
import { withInitialData } from './helpers';
|
||||
|
||||
|
@ -13,17 +13,20 @@ const ID = 'errorDistribution';
|
|||
const INITIAL_DATA = { buckets: [], totalHits: 0 };
|
||||
|
||||
export function getErrorDistribution(state) {
|
||||
return withInitialData(state.reduxRequest[ID], INITIAL_DATA);
|
||||
return withInitialData(state.reactReduxRequest[ID], INITIAL_DATA);
|
||||
}
|
||||
|
||||
export function ErrorDistributionRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, errorGroupId, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName, start, end, errorGroupId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
fn={loadErrorDistribution}
|
||||
shouldInvoke={Boolean(serviceName, start, end, errorGroupId)}
|
||||
args={[{ serviceName, start, end, errorGroupId, kuery }]}
|
||||
selector={getErrorDistribution}
|
||||
render={render}
|
|
@ -6,24 +6,27 @@
|
|||
|
||||
import React from 'react';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadErrorGroupDetails } from '../../services/rest';
|
||||
|
||||
const ID = 'errorGroupDetails';
|
||||
const INITIAL_DATA = {};
|
||||
|
||||
export function getErrorGroupDetails(state) {
|
||||
return withInitialData(state.reduxRequest[ID], INITIAL_DATA);
|
||||
return withInitialData(state.reactReduxRequest[ID], INITIAL_DATA);
|
||||
}
|
||||
|
||||
export function ErrorGroupDetailsRequest({ urlParams, render }) {
|
||||
const { serviceName, errorGroupId, start, end, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end && errorGroupId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
fn={loadErrorGroupDetails}
|
||||
shouldInvoke={Boolean(serviceName && start && end && errorGroupId)}
|
||||
args={[{ serviceName, start, end, errorGroupId, kuery }]}
|
||||
selector={getErrorGroupDetails}
|
||||
render={render}
|
|
@ -6,24 +6,27 @@
|
|||
|
||||
import React from 'react';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadErrorGroupList } from '../../services/rest';
|
||||
|
||||
const ID = 'errorGroupList';
|
||||
const INITIAL_DATA = [];
|
||||
|
||||
export function getErrorGroupList(state) {
|
||||
return withInitialData(state.reduxRequest[ID], INITIAL_DATA);
|
||||
return withInitialData(state.reactReduxRequest[ID], INITIAL_DATA);
|
||||
}
|
||||
|
||||
export function ErrorGroupDetailsRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, q, sortBy, sortOrder, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
fn={loadErrorGroupList}
|
||||
shouldInvoke={Boolean(serviceName && start && end)}
|
||||
args={[{ serviceName, start, end, q, sortBy, sortOrder, kuery }]}
|
||||
selector={getErrorGroupList}
|
||||
render={render}
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadLicense } from '../../services/rest';
|
||||
|
||||
const ID = 'license';
|
||||
|
@ -15,16 +15,11 @@ const INITIAL_DATA = {
|
|||
};
|
||||
|
||||
export function getLicense(state) {
|
||||
return withInitialData(state.reduxRequest[ID], INITIAL_DATA);
|
||||
return withInitialData(state.reactReduxRequest[ID], INITIAL_DATA);
|
||||
}
|
||||
|
||||
export function LicenceRequest({ render }) {
|
||||
return (
|
||||
<ReduxRequest
|
||||
id={ID}
|
||||
fn={loadLicense}
|
||||
selector={getLicense}
|
||||
render={render}
|
||||
/>
|
||||
<Request id={ID} fn={loadLicense} selector={getLicense} render={render} />
|
||||
);
|
||||
}
|
|
@ -9,7 +9,7 @@ import { createSelector } from 'reselect';
|
|||
import { getCharts } from '../selectors/chartSelectors';
|
||||
import { getUrlParams } from '../urlParams';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadCharts } from '../../services/rest';
|
||||
|
||||
const ID = 'overviewCharts';
|
||||
|
@ -23,16 +23,20 @@ const INITIAL_DATA = {
|
|||
|
||||
export const getOverviewCharts = createSelector(
|
||||
getUrlParams,
|
||||
state => withInitialData(state.reduxRequest[ID], INITIAL_DATA),
|
||||
state => withInitialData(state.reactReduxRequest[ID], INITIAL_DATA),
|
||||
getCharts
|
||||
);
|
||||
|
||||
export function OverviewChartsRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, transactionType, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end && transactionType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
shouldInvoke={Boolean(serviceName && start && end && transactionType)}
|
||||
fn={loadCharts}
|
||||
args={[{ serviceName, start, end, transactionType, kuery }]}
|
||||
selector={getOverviewCharts}
|
|
@ -8,27 +8,31 @@ import React from 'react';
|
|||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadServiceDetails } from '../../services/rest';
|
||||
|
||||
const ID = 'serviceDetails';
|
||||
const INITIAL_DATA = { types: [] };
|
||||
|
||||
export function getServiceDetails(state) {
|
||||
return withInitialData(state.reduxRequest[ID], INITIAL_DATA);
|
||||
return withInitialData(state.reactReduxRequest[ID], INITIAL_DATA);
|
||||
}
|
||||
|
||||
export function getDefaultTransactionType(state) {
|
||||
const types = _.get(state.reduxRequest.serviceDetails, 'data.types');
|
||||
const types = _.get(state.reactReduxRequest.serviceDetails, 'data.types');
|
||||
return _.first(types);
|
||||
}
|
||||
|
||||
export function ServiceDetailsRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
shouldInvoke={Boolean(serviceName && start && end)}
|
||||
fn={loadServiceDetails}
|
||||
args={[{ serviceName, start, end, kuery }]}
|
||||
selector={getServiceDetails}
|
|
@ -8,14 +8,14 @@ import React from 'react';
|
|||
import orderBy from 'lodash.orderby';
|
||||
import { createSelector } from 'reselect';
|
||||
import { loadServiceList } from '../../services/rest';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { withInitialData } from './helpers';
|
||||
|
||||
const ID = 'serviceList';
|
||||
const INITIAL_DATA = [];
|
||||
|
||||
export const getServiceList = createSelector(
|
||||
state => withInitialData(state.reduxRequest[ID], INITIAL_DATA),
|
||||
state => withInitialData(state.reactReduxRequest[ID], INITIAL_DATA),
|
||||
state => state.sorting.service,
|
||||
(serviceList, serviceSorting) => {
|
||||
const { key: sortKey, descending } = serviceSorting;
|
||||
|
@ -30,7 +30,7 @@ export const getServiceList = createSelector(
|
|||
export function ServiceListRequest({ urlParams, render }) {
|
||||
const { start, end, kuery } = urlParams;
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
fn={loadServiceList}
|
||||
args={[{ start, end, kuery }]}
|
|
@ -6,22 +6,26 @@
|
|||
|
||||
import React from 'react';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadSpans } from '../../services/rest';
|
||||
|
||||
const ID = 'spans';
|
||||
const INITIAL_DATA = {};
|
||||
|
||||
export function getSpans(state) {
|
||||
return withInitialData(state.reduxRequest[ID], INITIAL_DATA);
|
||||
return withInitialData(state.reactReduxRequest[ID], INITIAL_DATA);
|
||||
}
|
||||
|
||||
export function SpansRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, transactionId, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end && transactionId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
shouldInvoke={Boolean(serviceName && start && end && transactionId)}
|
||||
fn={loadSpans}
|
||||
selector={getSpans}
|
||||
args={[{ serviceName, start, end, transactionId, kuery }]}
|
|
@ -6,22 +6,26 @@
|
|||
|
||||
import React from 'react';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadTransaction } from '../../services/rest';
|
||||
|
||||
const ID = 'transactionDetails';
|
||||
const INITIAL_DATA = {};
|
||||
|
||||
export function getTransactionDetails(state) {
|
||||
return withInitialData(state.reduxRequest[ID], INITIAL_DATA);
|
||||
return withInitialData(state.reactReduxRequest[ID], INITIAL_DATA);
|
||||
}
|
||||
|
||||
export function TransactionDetailsRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, transactionId, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end && transactionId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
shouldInvoke={Boolean(serviceName && start && end && transactionId)}
|
||||
fn={loadTransaction}
|
||||
selector={getTransactionDetails}
|
||||
args={[{ serviceName, start, end, transactionId, kuery }]}
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
import React from 'react';
|
||||
import { withInitialData } from './helpers';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadTransactionDistribution } from '../../services/rest';
|
||||
|
||||
const INITIAL_DATA = { buckets: [], totalHits: 0 };
|
||||
|
||||
export function getTransactionDistribution(state) {
|
||||
return withInitialData(
|
||||
state.reduxRequest.transactionDistribution,
|
||||
state.reactReduxRequest.transactionDistribution,
|
||||
INITIAL_DATA
|
||||
);
|
||||
}
|
||||
|
@ -25,10 +25,14 @@ export function getDefaultTransactionId(state) {
|
|||
|
||||
export function TransactionDistributionRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, transactionName, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end && transactionName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id="transactionDistribution"
|
||||
shouldInvoke={Boolean(serviceName && start && end && transactionName)}
|
||||
fn={loadTransactionDistribution}
|
||||
args={[{ serviceName, start, end, transactionName, kuery }]}
|
||||
selector={getTransactionDistribution}
|
|
@ -7,14 +7,14 @@
|
|||
import React from 'react';
|
||||
import orderBy from 'lodash.orderby';
|
||||
import { createSelector } from 'reselect';
|
||||
import { ReduxRequest } from '../../components/shared/ReduxRequest';
|
||||
import { Request } from 'react-redux-request';
|
||||
import { loadTransactionList } from '../../services/rest';
|
||||
|
||||
const ID = 'transactionList';
|
||||
const INITIAL_DATA = [];
|
||||
|
||||
export const getTransactionList = createSelector(
|
||||
state => state.reduxRequest[ID],
|
||||
state => state.reactReduxRequest[ID],
|
||||
state => state.sorting.transaction,
|
||||
(transactionList = {}, transactionSorting) => {
|
||||
const { key: sortKey, descending } = transactionSorting;
|
||||
|
@ -32,10 +32,14 @@ export const getTransactionList = createSelector(
|
|||
|
||||
export function TransactionListRequest({ urlParams, render }) {
|
||||
const { serviceName, start, end, transactionType, kuery } = urlParams;
|
||||
|
||||
if (!(serviceName && start && end && transactionType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReduxRequest
|
||||
<Request
|
||||
id={ID}
|
||||
shouldInvoke={Boolean(serviceName && start && end && transactionType)}
|
||||
fn={loadTransactionList}
|
||||
args={[
|
||||
{
|
|
@ -8,13 +8,13 @@ import { combineReducers } from 'redux';
|
|||
import location from './location';
|
||||
import sorting from './sorting';
|
||||
import urlParams from './urlParams';
|
||||
import { reduxRequestReducer } from '../components/shared/ReduxRequest';
|
||||
import { reducer } from 'react-redux-request';
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
location,
|
||||
sorting,
|
||||
urlParams,
|
||||
reduxRequest: reduxRequestReducer
|
||||
reactReduxRequest: reducer
|
||||
});
|
||||
|
||||
export default rootReducer;
|
||||
|
|
|
@ -8,8 +8,8 @@ import _ from 'lodash';
|
|||
import { createSelector } from 'reselect';
|
||||
import { LOCATION_UPDATE } from './location';
|
||||
import { toQuery, legacyDecodeURIComponent } from '../utils/url';
|
||||
import { getDefaultTransactionId } from './reduxRequest/transactionDistribution';
|
||||
import { getDefaultTransactionType } from './reduxRequest/serviceDetails';
|
||||
import { getDefaultTransactionId } from './reactReduxRequest/transactionDistribution';
|
||||
import { getDefaultTransactionType } from './reactReduxRequest/serviceDetails';
|
||||
|
||||
// ACTION TYPES
|
||||
export const TIMEPICKER_UPDATE = 'TIMEPICKER_UPDATE';
|
||||
|
|
|
@ -12,9 +12,9 @@ exports[`KibanaLinkComponent should render correct markup 1`] = `
|
|||
exports[`RelativeLinkComponent should render correct markup 1`] = `
|
||||
<a
|
||||
className="euiLink euiLink--primary "
|
||||
href="/opbeans-backend/errors?_g=(refreshInterval:(display:Off,pause:!f,value:0),time:(from:now-2y,mode:quick,to:now))"
|
||||
href="/opbeans-node/errors?foo=bar&foo2=bar2"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Errors
|
||||
Go to Discover
|
||||
</a>
|
||||
`;
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { mount } from 'enzyme';
|
||||
import createHistory from 'history/createMemoryHistory';
|
||||
|
||||
import {
|
||||
toQuery,
|
||||
|
@ -48,35 +49,58 @@ describe('fromQuery', () => {
|
|||
});
|
||||
|
||||
describe('RelativeLinkComponent', () => {
|
||||
let history;
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
history = createHistory();
|
||||
history.location = {
|
||||
...history.location,
|
||||
pathname: '/opbeans-node/transactions',
|
||||
search: '?foo=bar'
|
||||
};
|
||||
|
||||
wrapper = mount(
|
||||
<MemoryRouter>
|
||||
<Router history={history}>
|
||||
<RelativeLinkComponent
|
||||
location={{
|
||||
pathname: '/opbeans-backend/transactions',
|
||||
search:
|
||||
'?_g=(refreshInterval:(display:Off,pause:!f,value:0),time:(from:now-2y,mode:quick,to:now))'
|
||||
}}
|
||||
path={'/opbeans-backend/errors'}
|
||||
query={{}}
|
||||
location={history.location}
|
||||
query={{ foo2: 'bar2' }}
|
||||
path={'/opbeans-node/errors'}
|
||||
>
|
||||
Errors
|
||||
Go to Discover
|
||||
</RelativeLinkComponent>
|
||||
</MemoryRouter>
|
||||
</Router>
|
||||
);
|
||||
});
|
||||
|
||||
it('should have correct url', () => {
|
||||
expect(wrapper.find('a').prop('href')).toBe(
|
||||
'/opbeans-backend/errors?_g=(refreshInterval:(display:Off,pause:!f,value:0),time:(from:now-2y,mode:quick,to:now))'
|
||||
'/opbeans-node/errors?foo=bar&foo2=bar2'
|
||||
);
|
||||
});
|
||||
|
||||
it('should render correct markup', () => {
|
||||
expect(toJson(wrapper)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should have initial location', () => {
|
||||
expect(history.location).toEqual(
|
||||
expect.objectContaining({
|
||||
pathname: '/opbeans-node/transactions',
|
||||
search: '?foo=bar'
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should update location on click', () => {
|
||||
wrapper.simulate('click', { button: 0 });
|
||||
expect(history.location).toEqual(
|
||||
expect.objectContaining({
|
||||
pathname: '/opbeans-node/errors',
|
||||
search: '?foo=bar&foo2=bar2'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('KibanaLinkComponent', () => {
|
||||
|
|
|
@ -4634,7 +4634,7 @@ lodash.isempty@^4.4.0:
|
|||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
|
||||
|
||||
lodash.isequal@^4.1.1:
|
||||
lodash.isequal@^4.1.1, lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
|
||||
|
@ -6094,6 +6094,14 @@ react-reconciler@^0.7.0:
|
|||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-redux-request@^1.5.5:
|
||||
version "1.5.5"
|
||||
resolved "https://registry.yarnpkg.com/react-redux-request/-/react-redux-request-1.5.5.tgz#693562b0d85293d9d16b02e13ea13f118950bb1d"
|
||||
dependencies:
|
||||
lodash.get "^4.4.2"
|
||||
lodash.isequal "^4.5.0"
|
||||
prop-types "^15.6.1"
|
||||
|
||||
react-redux@^5.0.5:
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946"
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -8172,7 +8172,7 @@ lodash.isempty@^4.4.0:
|
|||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
|
||||
|
||||
lodash.isequal@^4.0.0, lodash.isequal@^4.1.1:
|
||||
lodash.isequal@^4.0.0, lodash.isequal@^4.1.1, lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
|
||||
|
@ -10517,6 +10517,14 @@ react-reconciler@^0.7.0:
|
|||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-redux-request@^1.5.5:
|
||||
version "1.5.5"
|
||||
resolved "https://registry.yarnpkg.com/react-redux-request/-/react-redux-request-1.5.5.tgz#693562b0d85293d9d16b02e13ea13f118950bb1d"
|
||||
dependencies:
|
||||
lodash.get "^4.4.2"
|
||||
lodash.isequal "^4.5.0"
|
||||
prop-types "^15.6.1"
|
||||
|
||||
react-redux@^5.0.5, react-redux@^5.0.6:
|
||||
version "5.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue