Skip to content

Commit

Permalink
wip2
Browse files Browse the repository at this point in the history
  • Loading branch information
sorenlouv committed May 24, 2019
1 parent 7caabc0 commit 5b16901
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 69 deletions.
49 changes: 33 additions & 16 deletions x-pack/plugins/apm/public/components/app/Settings/AddSetting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
EuiFormRow,
EuiButton,
EuiFlexItem,
EuiFieldNumber
EuiFieldNumber,
EuiTitle
} from '@elastic/eui';
import { isEmpty } from 'lodash';
import { EuiFlexGroup } from '@elastic/eui';
Expand All @@ -32,7 +33,7 @@ export function AddSetting() {
const [serviceName, setServiceName] = useState<string | undefined>(undefined);
const [sampleRate, setSampleRate] = useState<number | undefined>(undefined);
const { data: serviceNames = [] } = useFetcher(loadCMServices, []);
const { data: environments = [], status } = useFetcher(
const { data: environments = [], status: environmentStatus } = useFetcher(
() => {
if (serviceName) {
return loadCMEnvironments({ serviceName });
Expand All @@ -53,7 +54,7 @@ export function AddSetting() {
useEffect(
() => {
if (!isEmpty(serviceNames)) {
setServiceName(serviceNames[0]);
setServiceName(undefined);
}
},
[serviceNames]
Expand All @@ -68,6 +69,9 @@ export function AddSetting() {

return (
<EuiForm>
<EuiTitle>
<h2>Agent configuration</h2>
</EuiTitle>
<form
onSubmit={async event => {
event.preventDefault();
Expand Down Expand Up @@ -101,7 +105,6 @@ export function AddSetting() {
pathname: `/settings`
});
} catch (error) {
console.log('Config could not be created', error);
toastNotifications.addDanger({
title: i18n.translate(
'xpack.apm.settings.cm.createConfigFailed',
Expand All @@ -111,10 +114,11 @@ export function AddSetting() {
}
}}
>
<EuiFlexGroup style={{ maxWidth: 600 }}>
<EuiFlexItem>
<EuiFormRow label="Service">
<EuiFlexGroup justifyContent="flexStart">
<EuiFlexItem grow={false}>
<EuiFormRow label="Service name">
<EuiSelect
hasNoInitialSelection
options={serviceNames.map(text => ({ text }))}
value={serviceName}
onChange={e => {
Expand All @@ -123,15 +127,20 @@ export function AddSetting() {
/>
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormRow
label="Environment"
label="Service environment"
error={
'You have created configurations for all environments in this service'
}
isInvalid={!hasAnyAvailableEnvironments && status !== 'loading'}
isInvalid={
!hasAnyAvailableEnvironments &&
(environmentStatus === 'success' ||
environmentStatus === 'failure')
}
>
<EuiSelect
hasNoInitialSelection
options={environmentOptions}
value={environment}
onChange={e => {
Expand All @@ -140,7 +149,7 @@ export function AddSetting() {
/>
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormRow label="Transaction sample rate">
<EuiFieldNumber
min={0}
Expand All @@ -155,14 +164,22 @@ export function AddSetting() {
/>
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFormRow label="&nbsp;">
<EuiButton
type="submit"
fill
disabled={!hasAnyAvailableEnvironments}
>
Save configuration
</EuiButton>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>

<p>serviceName: {serviceName}</p>
{/* <p>serviceName: {serviceName}</p>
<p>sampleRate: {sampleRate}</p>
<p>env: {environment}</p>
<EuiButton type="submit" fill disabled={!hasAnyAvailableEnvironments}>
Save configuration
</EuiButton>
<p>env: {environment}</p> */}
</form>
</EuiForm>
);
Expand Down
139 changes: 95 additions & 44 deletions x-pack/plugins/apm/public/components/app/Settings/ListSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,111 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
import {
EuiConfirmModal,
EUI_MODAL_CONFIRM_BUTTON,
EuiOverlayMask,
EuiTitle,
EuiIcon
} from '@elastic/eui';
import { loadCMList } from '../../../services/rest/apm/settings';
import { useFetcher } from '../../../hooks/useFetcher';
import { ITableColumn, ManagedTable } from '../../shared/ManagedTable';
import { CMListAPIResponse } from '../../../../server/lib/settings/cm/list_configurations';
import { APMLink } from '../../shared/Links/APMLink';

export const SERVICE_COLUMNS: Array<ITableColumn<CMListAPIResponse[0]>> = [
{
field: 'service.name',
name: i18n.translate('xpack.apm.settingsTable.serviceN ameColumnLabel', {
defaultMessage: 'Service name'
}),
width: '50%',
sortable: true,
render: (value: string) => value
},
{
field: 'service.environment',
name: i18n.translate('xpack.apm.settingsTable.environmentColumnLabel', {
defaultMessage: 'Service environment'
}),
sortable: true,
render: (value: string) => value
},
{
field: 'settings.sample_rate',
name: i18n.translate('xpack.apm.settingsTable.sampelRateColumnLabel', {
defaultMessage: 'Sample rate'
}),
sortable: true,
render: (value: string) => value
},
{
name: 'Delete',
actions: [
{
name: 'Delete',
description: 'Delete this config',
icon: 'trash',
color: 'danger',
type: 'icon',
onClick: () => {
console.log('deleting');
}
}
]
}
];
type Config = CMListAPIResponse[0];

export function ListSettings() {
const { data = [] } = useFetcher(loadCMList, []);
const [configToBeDeleted, setConfigToBeDeleted] = useState<Config | null>(
null
);

const COLUMNS: Array<ITableColumn<Config>> = [
{
field: 'service.name',
name: i18n.translate('xpack.apm.settingsTable.serviceN ameColumnLabel', {
defaultMessage: 'Service name'
}),
width: '50%',
sortable: true,
render: (value: string) => value
},
{
field: 'service.environment',
name: i18n.translate('xpack.apm.settingsTable.environmentColumnLabel', {
defaultMessage: 'Service environment'
}),
sortable: true,
render: (value: string) => value
},
{
field: 'settings.sample_rate',
name: i18n.translate('xpack.apm.settingsTable.sampelRateColumnLabel', {
defaultMessage: 'Sample rate'
}),
sortable: true,
render: (value: string) => value
},
{
name: 'Delete',
actions: [
{
name: 'Delete',
description: 'Delete this config',
icon: 'trash',
color: 'danger',
type: 'icon',
onClick: (config: Config) => {
setConfigToBeDeleted(config);
}
}
]
}
];

const deleteModal = configToBeDeleted ? (
<EuiOverlayMask>
<EuiConfirmModal
title={`Delete config for '${configToBeDeleted.service.name}' ${
configToBeDeleted.service.environment
? `(${configToBeDeleted.service.environment})`
: '(no environment)'
}`}
onCancel={() => {
setConfigToBeDeleted(null);
console.log('cancel');
}}
onConfirm={() => {
setConfigToBeDeleted(null);
console.log('confirm');
}}
cancelButtonText="Cancel"
confirmButtonText="Delete configuration"
buttonColor="danger"
defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON}
>
<p>
The sample rate will revert to the specified rate in the settings.yml
once the configured agent(s) reach the server
</p>
</EuiConfirmModal>
</EuiOverlayMask>
) : null;

return (
<ManagedTable columns={SERVICE_COLUMNS} items={data} initialPageSize={50} />
<>
{deleteModal}
<EuiTitle>
<h2>Agent configuration</h2>
</EuiTitle>
<ManagedTable columns={COLUMNS} items={data} initialPageSize={50} />
<APMLink path="/settings/new">
<EuiIcon type="plusInCircle" /> Add new configuration
</APMLink>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import { EuiBasicTable } from '@elastic/eui';
import { sortByOrder } from 'lodash';
import React, { Component } from 'react';
import { idx } from '@kbn/elastic-idx';
import { StringMap } from '../../../../typings/common';

// TODO: this should really be imported from EUI
export interface ITableColumn<T> {
field: string;
name: string;
actions?: StringMap[];
field?: string;
dataType?: string;
align?: string;
width?: string;
Expand Down
21 changes: 13 additions & 8 deletions x-pack/plugins/apm/public/hooks/useFetcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,21 @@ export function useFetcher<Response>(
useEffect(() => {
let didCancel = false;

dispatchStatus({ id, isLoading: true });
setResult({
data: result.data, // preserve data from previous state while loading next state
status: FETCH_STATUS.LOADING,
error: undefined
});

async function doFetch() {
const promise = fn();
if (!promise) {
return;
}

dispatchStatus({ id, isLoading: true });
setResult({
data: result.data, // preserve data from previous state while loading next state
status: FETCH_STATUS.LOADING,
error: undefined
});

try {
const data = await fn();
const data = await promise;
if (!didCancel) {
dispatchStatus({ id, isLoading: false });
setResult({
Expand Down

0 comments on commit 5b16901

Please sign in to comment.