phobos_checkpoint_ui 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/assets/index-b24a670cc064e5a7b78d-0.css +2 -0
  4. data/assets/index-b24a670cc064e5a7b78d-0.css.map +1 -0
  5. data/assets/{index-b2f95711135c455435c3-1.css → index-b24a670cc064e5a7b78d-1.css} +1 -1
  6. data/assets/{index-b2f95711135c455435c3-1.css.map → index-b24a670cc064e5a7b78d-1.css.map} +1 -1
  7. data/assets/{index-b2f95711135c455435c3.js → index-b24a670cc064e5a7b78d.js} +29 -29
  8. data/assets/index-b24a670cc064e5a7b78d.js.map +1 -0
  9. data/assets/index.html +2 -2
  10. data/frontend/src/actions/dashboard/failure-count/index.js +38 -0
  11. data/frontend/src/actions/dashboard/failure-count/index.spec.js +70 -0
  12. data/frontend/src/actions/index.js +4 -0
  13. data/frontend/src/api.js +1 -0
  14. data/frontend/src/components/badge/badge.scss +13 -0
  15. data/frontend/src/components/badge/index.js +85 -0
  16. data/frontend/src/components/badge/index.spec.js +64 -0
  17. data/frontend/src/components/header/index.js +8 -0
  18. data/frontend/src/components/search-input/index.js +3 -2
  19. data/frontend/src/reducers/dashboard/index.js +15 -0
  20. data/frontend/src/reducers/dashboard/index.spec.js +16 -0
  21. data/frontend/src/reducers/events-filters.js +4 -1
  22. data/frontend/src/reducers/index.js +2 -0
  23. data/frontend/src/reducers/index.spec.js +3 -0
  24. data/frontend/src/reducers/xhr-status.js +23 -1
  25. data/frontend/src/reducers/xhr-status.spec.js +31 -1
  26. data/frontend/src/routes.js +3 -1
  27. data/frontend/src/views/dashboard/index.js +68 -0
  28. data/frontend/src/views/dashboard/index.scss +5 -0
  29. data/frontend/src/views/events/search/index.js +7 -2
  30. data/frontend/src/views/events/search/index.scss +0 -7
  31. data/frontend/src/views/failures/search/index.js +7 -2
  32. data/frontend/src/views/failures/search/index.scss +0 -7
  33. data/frontend/src/views/style.js +43 -0
  34. data/lib/phobos_checkpoint_ui/version.rb +1 -1
  35. data/phobos_checkpoint_ui.gemspec +1 -1
  36. metadata +20 -10
  37. data/assets/index-b2f95711135c455435c3-0.css +0 -2
  38. data/assets/index-b2f95711135c455435c3-0.css.map +0 -1
  39. data/assets/index-b2f95711135c455435c3.js.map +0 -1
@@ -6,6 +6,7 @@ import {
6
6
  changeSearchInputFilterValue
7
7
  } from 'actions/search-input-filter'
8
8
 
9
+ import Paper from 'material-ui/Paper'
9
10
  import SelectField from 'material-ui/SelectField'
10
11
  import MenuItem from 'material-ui/MenuItem'
11
12
  import TextField from 'material-ui/TextField'
@@ -38,7 +39,7 @@ export class SearchInput extends Component {
38
39
 
39
40
  render () {
40
41
  return (
41
- <div className='search-input'>
42
+ <Paper className='search-input'>
42
43
  <SelectField
43
44
  style={{width: '140px'}}
44
45
  value={this.props.filterType || DEFAULT_FILTER_TYPE}
@@ -64,7 +65,7 @@ export class SearchInput extends Component {
64
65
  onClick={() => this.search()}
65
66
  style={{height: '50px', marginLeft: '20px'}}
66
67
  icon={this.getButtonIcon()} />
67
- </div>
68
+ </Paper>
68
69
  )
69
70
  }
70
71
 
@@ -0,0 +1,15 @@
1
+ import {
2
+ RECEIVE_FAILURE_COUNT
3
+ } from 'actions'
4
+
5
+ export default (state = {}, action) => {
6
+ switch (action.type) {
7
+ case RECEIVE_FAILURE_COUNT:
8
+ return {...state,
9
+ failureCount: action.data.count
10
+ }
11
+
12
+ default:
13
+ return state
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import {
2
+ RECEIVE_FAILURE_COUNT
3
+ } from 'actions'
4
+
5
+ import reducer from 'reducers/dashboard'
6
+
7
+ describe('reducers/dashboard', () => {
8
+ describe('for RECEIVE_FAILURE_COUNT', () => {
9
+ it('sets overviewVisible for the specific event to true', () => {
10
+ const currentState = {}
11
+ const action = { type: RECEIVE_FAILURE_COUNT, data: { count: 8 } }
12
+ const expectedState = { failureCount: 8 }
13
+ expect(reducer(currentState, action)).toEqual(expectedState)
14
+ })
15
+ })
16
+ })
@@ -1,4 +1,7 @@
1
- import { SEARCH_INPUT_CHANGE_FILTER_TYPE, SEARCH_INPUT_CHANGE_FILTER_VALUE } from 'actions'
1
+ import {
2
+ SEARCH_INPUT_CHANGE_FILTER_TYPE,
3
+ SEARCH_INPUT_CHANGE_FILTER_VALUE
4
+ } from 'actions'
2
5
 
3
6
  export const DEFAULT_FILTER_TYPE = 'entity_id'
4
7
  const initialState = { type: DEFAULT_FILTER_TYPE }
@@ -2,6 +2,7 @@ import { combineReducers } from 'redux'
2
2
  import { routerReducer } from 'react-router-redux'
3
3
 
4
4
  import events from 'reducers/events'
5
+ import dashboard from 'reducers/dashboard'
5
6
  import failures from 'reducers/failures'
6
7
  import eventDetails from 'reducers/event-details'
7
8
  import failureDetails from 'reducers/failures/details'
@@ -10,6 +11,7 @@ import xhrStatus from 'reducers/xhr-status'
10
11
  import flashMessages from 'reducers/flash-messages'
11
12
 
12
13
  export default combineReducers({
14
+ dashboard,
13
15
  xhrStatus,
14
16
  flashMessages,
15
17
  eventsFilters,
@@ -3,11 +3,14 @@ import reducer from 'reducers'
3
3
  describe('reducers', () => {
4
4
  it('without actions returns the initial state', () => {
5
5
  expect(reducer(undefined, {})).toEqual({
6
+ dashboard: {},
6
7
  xhrStatus: {
7
8
  isFetchingEvents: false,
8
9
  isRetryingEvent: false,
9
10
  isRetryingFailure: false,
10
11
  isDeletingFailure: false,
12
+ isFetchingFailureCount: false,
13
+ fetchFailureCountFailed: false,
11
14
  isFetchingEventDetails: false,
12
15
  currentEventsOffset: 0,
13
16
  lastEventsLoadSize: 0
@@ -19,15 +19,20 @@ import {
19
19
  RECEIVE_EVENT_RETRY,
20
20
  REQUEST_EVENT_RETRY_FAILED,
21
21
  REQUEST_EVENT_DETAILS,
22
- RECEIVE_EVENT_DETAILS
22
+ RECEIVE_EVENT_DETAILS,
23
+ REQUEST_FAILURE_COUNT,
24
+ RECEIVE_FAILURE_COUNT,
25
+ REQUEST_FAILURE_COUNT_FAILED
23
26
  } from 'actions'
24
27
 
25
28
  const initialState = {
26
29
  isFetchingEvents: false,
30
+ isFetchingFailureCount: false,
27
31
  isRetryingEvent: false,
28
32
  isRetryingFailure: false,
29
33
  isDeletingFailure: false,
30
34
  isFetchingEventDetails: false,
35
+ fetchFailureCountFailed: false,
31
36
  currentEventsOffset: 0,
32
37
  lastEventsLoadSize: 0
33
38
  }
@@ -114,6 +119,23 @@ export default (state = initialState, action) => {
114
119
  isFetchingEventDetails: false
115
120
  }
116
121
 
122
+ case REQUEST_FAILURE_COUNT:
123
+ return {...state,
124
+ isFetchingFailureCount: true
125
+ }
126
+
127
+ case RECEIVE_FAILURE_COUNT:
128
+ return {...state,
129
+ isFetchingFailureCount: false,
130
+ fetchFailureCountFailed: false
131
+ }
132
+
133
+ case REQUEST_FAILURE_COUNT_FAILED:
134
+ return {...state,
135
+ isFetchingFailureCount: false,
136
+ fetchFailureCountFailed: true
137
+ }
138
+
117
139
  default:
118
140
  return state
119
141
  }
@@ -17,7 +17,10 @@ import {
17
17
  REQUEST_FAILURE_DELETE_FAILED,
18
18
  REQUEST_EVENT_RETRY,
19
19
  RECEIVE_EVENT_RETRY,
20
- REQUEST_EVENT_RETRY_FAILED
20
+ REQUEST_EVENT_RETRY_FAILED,
21
+ REQUEST_FAILURE_COUNT,
22
+ RECEIVE_FAILURE_COUNT,
23
+ REQUEST_FAILURE_COUNT_FAILED
21
24
  } from 'actions'
22
25
 
23
26
  import reducer from 'reducers/xhr-status'
@@ -194,6 +197,33 @@ describe('reducers/xhr-status', () => {
194
197
  })
195
198
  })
196
199
 
200
+ describe('for REQUEST_FAILURE_COUNT', () => {
201
+ it('enables isFetchingFailureCount', () => {
202
+ const currentState = { isFetchingFailureCount: false }
203
+ const action = { type: REQUEST_FAILURE_COUNT }
204
+ const expectedState = { isFetchingFailureCount: true }
205
+ expect(reducer(currentState, action)).toEqual(expectedState)
206
+ })
207
+ })
208
+
209
+ describe('for RECEIVE_FAILURE_COUNT', () => {
210
+ it('disables isFetchingFailureCount', () => {
211
+ const currentState = { isFetchingFailureCount: true, fetchFailureCountFailed: true }
212
+ const action = { type: RECEIVE_FAILURE_COUNT }
213
+ const expectedState = { isFetchingFailureCount: false, fetchFailureCountFailed: false }
214
+ expect(reducer(currentState, action)).toEqual(expectedState)
215
+ })
216
+ })
217
+
218
+ describe('for REQUEST_FAILURE_COUNT_FAILED', () => {
219
+ it('disables isFetchingFailureCount', () => {
220
+ const currentState = { isFetchingFailureCount: true, fetchFailureCountFailed: false }
221
+ const action = { type: REQUEST_FAILURE_COUNT_FAILED }
222
+ const expectedState = { isFetchingFailureCount: false, fetchFailureCountFailed: true }
223
+ expect(reducer(currentState, action)).toEqual(expectedState)
224
+ })
225
+ })
226
+
197
227
  describe('for default', () => {
198
228
  it('returns the currentState', () => {
199
229
  const currentState = { current: true }
@@ -8,13 +8,15 @@ import EventsSearch from 'views/events/search'
8
8
  import EventDetails from 'views/events/details'
9
9
  import FailuresSearch from 'views/failures/search'
10
10
  import FailureDetails from 'views/failures/details'
11
+ import Dashboard from 'views/dashboard'
11
12
 
12
13
  export const history = syncHistoryWithStore(browserHistory, store)
13
14
 
14
15
  export default (
15
16
  <Router history={history}>
16
17
  <Route path='/' component={Layout}>
17
- <IndexRedirect to='/events' />
18
+ <IndexRedirect to='/dashboard' />
19
+ <Route path='/dashboard' component={Dashboard} />
18
20
  <Route path='/events' component={EventsSearch} />
19
21
  <Route path='/events/:id' component={EventDetails} />
20
22
  <Route path='/failures' component={FailuresSearch} />
@@ -0,0 +1,68 @@
1
+ import React, { Component, PropTypes } from 'react'
2
+ import { connect } from 'react-redux'
3
+
4
+ import Badge from 'components/badge'
5
+ import Paper from 'material-ui/Paper'
6
+ import { fetchFailureCount } from 'actions/dashboard/failure-count'
7
+ import { style } from 'views/style'
8
+
9
+ export class Dashboard extends Component {
10
+ static get propTypes () {
11
+ return {
12
+ fetchFailureCount: PropTypes.func.isRequired,
13
+
14
+ xhrStatus: PropTypes.shape({
15
+ isFetchingFailureCount: PropTypes.bool
16
+ })
17
+ }
18
+ }
19
+
20
+ componentDidMount () {
21
+ this.props.fetchFailureCount()
22
+
23
+ this.intervalId = setInterval(() => {
24
+ this.props.fetchFailureCount()
25
+ }, 10000)
26
+ }
27
+
28
+ componentWillUnmount () {
29
+ clearInterval(this.intervalId)
30
+ }
31
+
32
+ render () {
33
+ return (
34
+ <Paper zDepth={3} className='dashboard' style={style.view}>
35
+ <div style={style.title}>
36
+ Dashboard
37
+ </div>
38
+ <div style={style.body}>
39
+ <div style={style.row}>
40
+ <div style={style.heading}>
41
+ There are
42
+ </div>
43
+ {
44
+ <Badge
45
+ classCondition={this.props.dashboard.failureCount === 0}
46
+ text={this.props.dashboard.failureCount}
47
+ failed={this.props.xhrStatus.fetchFailureCountFailed}
48
+ loading={this.isLoadingFirstPage()} />
49
+ }
50
+ <div style={style.altHeading}>
51
+ failures
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </Paper>
56
+ )
57
+ }
58
+
59
+ isLoadingFirstPage () {
60
+ return this.props.dashboard.failureCount === null && this.props.xhrStatus.isFetchingFailureCount
61
+ }
62
+ }
63
+
64
+ export default connect(
65
+ (state) => state, {
66
+ fetchFailureCount
67
+ }
68
+ )(Dashboard)
@@ -0,0 +1,5 @@
1
+ .dashboard {
2
+ font-size: 30px;
3
+ color: #333;
4
+ min-height: 720px;
5
+ }
@@ -1,6 +1,7 @@
1
1
  import React, { Component, PropTypes } from 'react'
2
2
  import { connect } from 'react-redux'
3
3
 
4
+ import Paper from 'material-ui/Paper'
4
5
  import LoadMore from 'components/load-more'
5
6
  import EmptyEvent from 'components/empty-event'
6
7
  import EventsList from 'components/events-list'
@@ -10,6 +11,7 @@ import CircularProgress from 'material-ui/CircularProgress'
10
11
  import { fetchSearchResults, loadMoreSearchResults, triggerSearch } from 'actions/events-search'
11
12
  import { changeSearchInputFilterType, changeSearchInputFilterValue } from 'actions/search-input-filter'
12
13
  import { showEventOverview } from 'actions/event-overview'
14
+ import { style } from 'views/style'
13
15
 
14
16
  export class EventsSearch extends Component {
15
17
  static get propTypes () {
@@ -68,7 +70,10 @@ export class EventsSearch extends Component {
68
70
  const { type, value } = this.props.eventsFilters
69
71
 
70
72
  return (
71
- <div className='events-search'>
73
+ <Paper zDepth={3} className='events-search' style={style.view}>
74
+ <div style={style.title}>
75
+ Event search
76
+ </div>
72
77
  <SearchInput triggerSearch={this.props.triggerSearch} filterType={type} filterValue={value}/>
73
78
  <div>
74
79
  <EventsList events={events} />
@@ -83,7 +88,7 @@ export class EventsSearch extends Component {
83
88
  <CircularProgress />
84
89
  </div>
85
90
  }
86
- </div>
91
+ </Paper>
87
92
  )
88
93
  }
89
94
 
@@ -1,11 +1,4 @@
1
1
  .events-search {
2
- max-width: 1020px;
3
- min-height: 100%;
4
-
5
- background-color: #e4e4e4;
6
- margin: 0 auto;
7
- padding: 20px 0;
8
-
9
2
  .page-loader {
10
3
  text-align: center;
11
4
  padding: 50px 0;
@@ -1,6 +1,7 @@
1
1
  import React, { Component, PropTypes } from 'react'
2
2
  import { connect } from 'react-redux'
3
3
 
4
+ import Paper from 'material-ui/Paper'
4
5
  import LoadMore from 'components/load-more'
5
6
  import EmptyFailure from 'components/failure/empty'
6
7
  import FailuresList from 'components/failure/list'
@@ -10,6 +11,7 @@ import CircularProgress from 'material-ui/CircularProgress'
10
11
  import { fetchSearchResults, loadMoreSearchResults, triggerSearch } from 'actions/failures/search'
11
12
  import { changeSearchInputFilterType, changeSearchInputFilterValue } from 'actions/search-input-filter'
12
13
  import { showEventOverview } from 'actions/event-overview'
14
+ import { style } from 'views/style'
13
15
 
14
16
  export class FailuresSearch extends Component {
15
17
  static get propTypes () {
@@ -76,7 +78,10 @@ export class FailuresSearch extends Component {
76
78
  const { type, value } = this.props.eventsFilters
77
79
 
78
80
  return (
79
- <div className='failures-search'>
81
+ <Paper zDepth={3} className='failures-search' style={style.view}>
82
+ <div style={style.title}>
83
+ Failure search
84
+ </div>
80
85
  <SearchInput triggerSearch={this.props.triggerSearch} filterType={type} filterValue={value}/>
81
86
  <div>
82
87
  <FailuresList failures={failures} />
@@ -91,7 +96,7 @@ export class FailuresSearch extends Component {
91
96
  <CircularProgress />
92
97
  </div>
93
98
  }
94
- </div>
99
+ </Paper>
95
100
  )
96
101
  }
97
102
 
@@ -1,11 +1,4 @@
1
1
  .failures-search {
2
- max-width: 1020px;
3
- min-height: 100%;
4
-
5
- background-color: #e4e4e4;
6
- margin: 0 auto;
7
- padding: 20px 0;
8
-
9
2
  .page-loader {
10
3
  text-align: center;
11
4
  padding: 50px 0;
@@ -0,0 +1,43 @@
1
+ import {
2
+ grey200,
3
+ grey50,
4
+ blueGrey300
5
+ } from 'material-ui/styles/colors'
6
+
7
+ export const style = {
8
+ view: {
9
+ maxWidth: '1020px',
10
+ minHeigh: '100%',
11
+ backgroundColor: grey200,
12
+ margin: '0 auto'
13
+ },
14
+ title: {
15
+ padding: '20px 20px',
16
+ color: grey50,
17
+ backgroundColor: blueGrey300,
18
+ fontSize: '20px',
19
+ fontWeight: 'lighter',
20
+ fontFamily: 'Roboto',
21
+ marginBottom: '20px'
22
+ },
23
+ body: {
24
+ display: 'flex',
25
+ padding: '0 20px',
26
+ justifyContent: 'center'
27
+ },
28
+ row: {
29
+ display: 'flex',
30
+ alignItems: 'flex-start'
31
+ },
32
+ heading: {
33
+ fontSize: '24px',
34
+ fontWeight: 'lighter',
35
+ fontFamily: 'Roboto'
36
+ },
37
+ altHeading: {
38
+ fontSize: '24px',
39
+ fontWeight: 'lighter',
40
+ fontFamily: 'Roboto',
41
+ alignSelf: 'flex-end'
42
+ }
43
+ }
@@ -1,3 +1,3 @@
1
1
  module PhobosCheckpointUI
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -50,5 +50,5 @@ Gem::Specification.new do |spec|
50
50
 
51
51
  spec.add_dependency 'rake'
52
52
  spec.add_dependency 'sinatra'
53
- spec.add_dependency 'phobos_db_checkpoint', '~> 2.0'
53
+ spec.add_dependency 'phobos_db_checkpoint', '~> 2.4'
54
54
  end