Skip to content

Commit

Permalink
Display errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalastax committed Oct 25, 2016
1 parent bf64834 commit 05e72e5
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
25 changes: 25 additions & 0 deletions src/components/errors/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from "react"
import { connect } from "react-redux"
import { State } from "model"

export interface ErrorDisplayProps {
latestError: string | undefined
}

export class ErrorDisplay extends React.Component<ErrorDisplayProps, void> {
public render() {
return (
<div>
{this.props.latestError}
</div>
)
}
}

function mapStateToProps(state: State): ErrorDisplayProps {
return {
latestError: state.errors.latestError,
}
}

export default connect(mapStateToProps)(ErrorDisplay)
2 changes: 2 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "./index.styl"
import CalendarWeek from "components/calendar-week"
import CalendarInput from "components/input"
import CalendarSelection from "components/selection"
import ErrorDisplay from "components/errors"


const store = configureStore({})
Expand All @@ -26,6 +27,7 @@ class Out extends React.Component<void, void> {
<div>
<CalendarInput />
<CalendarSelection />
<ErrorDisplay />
<CalendarWeek />
</div>
)
Expand Down
10 changes: 7 additions & 3 deletions src/model/modules/calendars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Action as ReduxAction, MiddlewareAPI } from "redux"
import { Observable } from "rxjs"
import { ActionsObservable } from "redux-observable"
import { IcsInterval, URL, SelectionChange, State } from "model"
import actionCreator, { isType, Action } from "redux-typescript-actions"
import { errorTranslators } from "./errors"
import actionCreator, { isType, Action, FailedAction } from "redux-typescript-actions"
import { ajax } from "rxjs/observable/dom/ajax.js"
import { parseICS, IcsEntry } from "ical/ical.js"
import * as moment from "moment"
Expand All @@ -17,14 +18,17 @@ export interface CalendarsState {
export const REQUEST_URL = actionCreator.async<URL, IcsInterval[], Error>("SCHEDULE_REQUEST_URL")
export const SELECTION_CHANGE = actionCreator<SelectionChange>("SELECTION_CHANGE")

errorTranslators[REQUEST_URL.failed.type] = (x: Action<FailedAction<URL, Error>>) =>
`Failed to get ${x.payload.params}: ${JSON.stringify(x.payload.error, ["message", "arguments", "type", "name"])}`

function isDayStart(m: moment.Moment): boolean {
return m.isSame(moment(m).startOf("day"))
}

export const requestUrlEpic = (action$: ActionsObservable<URL>, store: MiddlewareAPI<State>) =>
export const requestUrlEpic = (action$: ActionsObservable<Action<URL>>, store: MiddlewareAPI<State>) =>
action$
.ofType(REQUEST_URL.started.type)
.mergeMap((action: Action<string>) => {
.mergeMap((action: Action<URL>) => {
if (store.getState().schedule[action.payload]) {
return Observable.empty()
}
Expand Down
43 changes: 43 additions & 0 deletions src/model/modules/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Action as ReduxAction, MiddlewareAPI } from "redux"
import {
State,
} from "model"
import actionCreator, { isType, Action } from "redux-typescript-actions"
import { ActionsObservable } from "redux-observable"

export interface ErrorsState {
latestError?: string,
}

export const NEW_ERROR = actionCreator<string>("NEW_ERROR")

interface ET {
[key: string]: (x: ReduxAction) => string | undefined
}


// Add to this object to add more error translations
export const errorTranslators: ET = {}

export const errorsEpic = (action$: ActionsObservable<ReduxAction>, store: MiddlewareAPI<State>) =>
action$
.map<ReduxAction, Action<string> | undefined>(x => {
const f = errorTranslators[x.type]
if (f !== undefined) {
const fx = f(x)
if (fx !== undefined) {
return NEW_ERROR(fx)
}
}
})
.filterUndefined()


export const errors = (state = {}, action: ReduxAction): ErrorsState => {
if (isType(action, NEW_ERROR)) {
return {
latestError: action.payload,
}
}
return state
}
4 changes: 4 additions & 0 deletions src/model/modules/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ import { combineReducers } from "redux"
import { combineEpics } from "redux-observable"
import { requestUrlEpic, schedule, CalendarsState } from "./calendars"
import { tree, TreeState, toggleEpic } from "./tree"
import { errors, ErrorsState, errorsEpic } from "./errors"

export const rootEpic = combineEpics(
errorsEpic,
requestUrlEpic,
toggleEpic
)

export interface State {
schedule: CalendarsState
tree: TreeState
errors: ErrorsState
}

export const rootReducer = combineReducers<State>({
errors,
schedule,
tree,
})

0 comments on commit 05e72e5

Please sign in to comment.