WIP Introduce LOAD_SERVICES

pull/3460/head
Andrew Watkins 2018-05-17 13:27:45 -07:00
parent b9e270692c
commit d249fd6d9b
9 changed files with 179 additions and 64 deletions

View File

@ -17,8 +17,41 @@ import {
import {Source, Kapacitor} from 'src/types'
export type Action = ActionLoadSources | ActionUpdateSource
export type Action =
| ActionLoadSources
| ActionUpdateSource
| ActionAddSource
| ActionFetchKapacitors
| ActionSetActiveKapacitor
| ActionDeleteKapacitor
| ActionLoadServices
// Load Services
export type LoadServices = (
source: Source,
services: Service[]
) => ActionLoadServices
export interface ActionLoadServices {
type: 'LOAD_SERVICES'
payload: {
source: Source
services: Service[]
}
}
export const loadServices = (
source: Source,
services: Service[]
): ActionLoadServices => ({
type: 'LOAD_SERVICES',
payload: {
source,
services,
},
})
// Load Sources
export type LoadSources = (sources: Source[]) => ActionLoadSources
export interface ActionLoadSources {
type: 'LOAD_SOURCES'

View File

@ -1,15 +1,28 @@
import _ from 'lodash'
import {Source, Kapacitor} from 'src/types'
import {Action} from 'src/shared/actions/sources'
const getInitialState = () => []
export const initialState: Source[] = []
const initialState = getInitialState()
const sourcesReducer = (state = initialState, action) => {
const sourcesReducer = (state = initialState, action: Action): Source[] => {
switch (action.type) {
case 'LOAD_SOURCES': {
return action.payload.sources
}
case 'LOAD_SERVICES': {
const {services} = action.payload
const newState = state.map<Source>(source => {
if (source.id === action.payload.source.id) {
return {...source, services}
}
return {...source}
})
return newState
}
case 'SOURCE_UPDATED': {
const {source} = action.payload
const updatedIndex = state.findIndex(s => s.id === source.id)
@ -59,7 +72,11 @@ const sourcesReducer = (state = initialState, action) => {
const {kapacitor} = action.payload
const updatedSources = _.cloneDeep(state)
updatedSources.forEach(source => {
const index = _.findIndex(source.kapacitors, k => k.id === kapacitor.id)
const index = _.findIndex<Kapacitor>(
source.kapacitors,
k => k.id === kapacitor.id
)
if (index >= 0) {
source.kapacitors.splice(index, 1)
}

View File

@ -13,6 +13,7 @@ const InfluxTableHead: SFC<{}> = (): ReactElement<
<th className="source-table--connect-col" />
<th>InfluxDB Connection</th>
<th className="text-right" />
<th>Services Connection</th>
<th>
Kapacitor Connection
<QuestionMarkTooltip

View File

@ -45,6 +45,7 @@ class InfluxTableRow extends PureComponent<Props> {
/>
</Authorized>
</td>
<td>Services Connection</td>
<td className="source-table--kapacitor">
<KapacitorDropdown
source={source}

14
ui/src/types/services.ts Normal file
View File

@ -0,0 +1,14 @@
interface Service {
id?: string
url: string
name: string
type: string
username?: string
password?: string
active: boolean
insecureSkipVerify: boolean
links: {
self: string
proxy: string
}
}

View File

@ -17,6 +17,7 @@ export interface Source {
defaultRP: string
links: SourceLinks
kapacitors?: Kapacitor[] // this field does not exist on the server type for Source and is added in the client in the reducer for loading kapacitors.
services?: Service[]
}
export interface SourceLinks {

View File

@ -93,6 +93,20 @@ export const kapacitor = {
},
}
export const service = {
url: 'localhost:8082',
type: 'ifql',
name: 'IFQL',
username: '',
password: '',
active: false,
insecureSkipVerify: false,
links: {
proxy: '/chronograf/v1/sources/1/services/2/proxy',
self: '/chronograf/v1/sources/1/services/2',
},
}
export const kapacitorRules = [
{
id: '1',

View File

@ -1,58 +0,0 @@
import reducer from 'shared/reducers/sources'
import {updateSource, addSource} from 'shared/actions/sources'
describe('Shared.Reducers.sources', () => {
it('can correctly show default sources when adding a source', () => {
let state = []
state = reducer(
state,
addSource({
id: '1',
default: true,
})
)
state = reducer(
state,
addSource({
id: '2',
default: true,
})
)
expect(state.filter(s => s.default).length).toBe(1)
})
it('can correctly show default sources when updating a source', () => {
let state = []
state = reducer(
state,
addSource({
id: '1',
default: true,
})
)
state = reducer(
state,
addSource({
id: '2',
default: true,
})
)
state = reducer(
state,
updateSource({
id: '1',
default: true,
})
)
expect(state.find(({id}) => id === '1').default).toBe(true)
expect(state.find(({id}) => id === '2').default).toBe(false)
})
})

View File

@ -0,0 +1,92 @@
import reducer, {initialState} from 'src/shared/reducers/sources'
import {
updateSource,
addSource,
loadServices,
loadSources,
} from 'src/shared/actions/sources'
import {source, service} from 'test/resources'
describe('Shared.Reducers.sources', () => {
it('can LOAD_SOURCES', () => {
const expected = [{...source, id: '1'}]
const actual = reducer(initialState, loadSources(expected))
expect(actual).toEqual(expected)
})
describe('ADD_SOURCES', () => {
it('can ADD_SOURCES', () => {
let state = []
state = reducer(
state,
addSource({
...source,
id: '1',
default: true,
})
)
state = reducer(
state,
addSource({
...source,
id: '2',
default: true,
})
)
expect(state.filter(s => s.default).length).toBe(1)
})
it('can correctly show default sources when updating a source', () => {
let state = []
state = reducer(
initialState,
addSource({
...source,
id: '1',
default: true,
})
)
state = reducer(
state,
addSource({
...source,
id: '2',
default: true,
})
)
state = reducer(
state,
updateSource({
...source,
id: '1',
default: true,
})
)
expect(state.find(({id}) => id === '1').default).toBe(true)
expect(state.find(({id}) => id === '2').default).toBe(false)
})
})
describe('LOAD_SERVICES', () => {
it('correctly loads the services', () => {
const s1 = {...service, id: '1'}
const s2 = {...service, id: '2'}
const expected = [s1, s2]
const state = reducer(initialState, loadSources([source]))
const actual = reducer(state, loadServices(source, expected))
expect(actual[0].services).toEqual(expected)
})
})
})