forked from astuto/astuto
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Redux and use it for state management
- Loading branch information
Showing
22 changed files
with
657 additions
and
247 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
export const SET_SEARCH_FILTER = 'SET_SEARCH_FILTER'; | ||
interface SetSearchFilterAction { | ||
type: typeof SET_SEARCH_FILTER; | ||
searchQuery: string; | ||
} | ||
|
||
export const SET_POST_STATUS_FILTER = 'SET_POST_STATUS_FILTER'; | ||
interface SetPostStatusFilterAction { | ||
type: typeof SET_POST_STATUS_FILTER; | ||
postStatusId: number; | ||
} | ||
|
||
|
||
export const setSearchFilter = (searchQuery: string): SetSearchFilterAction => ({ | ||
type: SET_SEARCH_FILTER, | ||
searchQuery, | ||
}); | ||
|
||
export const setPostStatusFilter = (postStatusId: number): SetPostStatusFilterAction => ({ | ||
type: SET_POST_STATUS_FILTER, | ||
postStatusId, | ||
}); | ||
|
||
|
||
export type ChangeFiltersActionTypes = | ||
SetSearchFilterAction | | ||
SetPostStatusFilterAction; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Action } from 'redux'; | ||
import { ThunkAction } from 'redux-thunk'; | ||
|
||
import IPostStatus from '../interfaces/IPostStatus'; | ||
|
||
import { State } from '../reducers/rootReducer'; | ||
|
||
export const POST_STATUSES_REQUEST_START = 'POST_STATUSES_REQUEST_START'; | ||
interface PostStatusesRequestStartAction { | ||
type: typeof POST_STATUSES_REQUEST_START; | ||
} | ||
|
||
export const POST_STATUSES_REQUEST_SUCCESS = 'POST_STATUSES_REQUEST_SUCCESS'; | ||
interface PostStatusesRequestSuccessAction { | ||
type: typeof POST_STATUSES_REQUEST_SUCCESS; | ||
postStatuses: Array<IPostStatus>; | ||
} | ||
|
||
export const POST_STATUSES_REQUEST_FAILURE = 'POST_STATUSES_REQUEST_FAILURE'; | ||
interface PostStatusesRequestFailureAction { | ||
type: typeof POST_STATUSES_REQUEST_FAILURE; | ||
error: string; | ||
} | ||
|
||
export type PostStatusesRequestActionTypes = | ||
PostStatusesRequestStartAction | | ||
PostStatusesRequestSuccessAction | | ||
PostStatusesRequestFailureAction | ||
|
||
|
||
const postStatusesRequestStart = (): PostStatusesRequestActionTypes => ({ | ||
type: POST_STATUSES_REQUEST_START, | ||
}); | ||
|
||
const postStatusesRequestSuccess = ( | ||
postStatuses: Array<IPostStatus> | ||
): PostStatusesRequestActionTypes => ({ | ||
type: POST_STATUSES_REQUEST_SUCCESS, | ||
postStatuses, | ||
}); | ||
|
||
const postStatusesRequestFailure = (error: string): PostStatusesRequestActionTypes => ({ | ||
type: POST_STATUSES_REQUEST_FAILURE, | ||
error, | ||
}); | ||
|
||
export const requestPostStatuses = (): ThunkAction<void, State, null, Action<string>> => ( | ||
async (dispatch) => { | ||
dispatch(postStatusesRequestStart()); | ||
|
||
try { | ||
const response = await fetch('/post_statuses'); | ||
const json = await response.json(); | ||
dispatch(postStatusesRequestSuccess(json)); | ||
} catch (e) { | ||
dispatch(postStatusesRequestFailure(e)); | ||
} | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { Action } from 'redux'; | ||
import { ThunkAction } from 'redux-thunk'; | ||
|
||
import IPostJSON from '../interfaces/json/IPost'; | ||
|
||
import { State } from '../reducers/rootReducer'; | ||
|
||
export const POSTS_REQUEST_START = 'POSTS_REQUEST_START'; | ||
interface PostsRequestStartAction { | ||
type: typeof POSTS_REQUEST_START; | ||
} | ||
|
||
export const POSTS_REQUEST_SUCCESS = 'POSTS_REQUEST_SUCCESS'; | ||
interface PostsRequestSuccessAction { | ||
type: typeof POSTS_REQUEST_SUCCESS; | ||
posts: Array<IPostJSON>; | ||
page: number; | ||
} | ||
|
||
export const POSTS_REQUEST_FAILURE = 'POSTS_REQUEST_FAILURE'; | ||
interface PostsRequestFailureAction { | ||
type: typeof POSTS_REQUEST_FAILURE; | ||
error: string; | ||
} | ||
|
||
export type PostsRequestActionTypes = | ||
PostsRequestStartAction | | ||
PostsRequestSuccessAction | | ||
PostsRequestFailureAction; | ||
|
||
|
||
const postsRequestStart = (): PostsRequestActionTypes => ({ | ||
type: POSTS_REQUEST_START, | ||
}); | ||
|
||
const postsRequestSuccess = (posts: Array<IPostJSON>, page: number): PostsRequestActionTypes => ({ | ||
type: POSTS_REQUEST_SUCCESS, | ||
posts, | ||
page, | ||
}); | ||
|
||
const postsRequestFailure = (error: string): PostsRequestActionTypes => ({ | ||
type: POSTS_REQUEST_FAILURE, | ||
error, | ||
}); | ||
|
||
export const requestPosts = ( | ||
boardId: number, | ||
page: number, | ||
searchQuery: string, | ||
postStatusId: number, | ||
): ThunkAction<void, State, null, Action<string>> => async (dispatch) => { | ||
dispatch(postsRequestStart()); | ||
|
||
try { | ||
let params = ''; | ||
params += `page=${page}`; | ||
params += `&board_id=${boardId}`; | ||
if (searchQuery) params += `&search=${searchQuery}`; | ||
if (postStatusId) params += `&post_status_id=${postStatusId}`; | ||
|
||
const response = await fetch(`/posts?${params}`); | ||
const json = await response.json(); | ||
dispatch(postsRequestSuccess(json, page)); | ||
} catch (e) { | ||
dispatch(postsRequestFailure(e)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import * as React from 'react'; | ||
|
||
import NewPost from './NewPost'; | ||
import SearchFilter from './SearchFilter'; | ||
import PostStatusFilter from './PostStatusFilter'; | ||
import PostList from './PostList'; | ||
|
||
import IBoard from '../../interfaces/IBoard'; | ||
import IPost from '../../interfaces/IPost'; | ||
|
||
import { PostsState } from '../../reducers/postsReducer'; | ||
import { PostStatusesState } from '../../reducers/postStatusesReducer'; | ||
|
||
interface Props { | ||
board: IBoard; | ||
isLoggedIn: boolean; | ||
authenticityToken: string; | ||
posts: PostsState; | ||
postStatuses: PostStatusesState; | ||
|
||
requestPosts( | ||
boardId: number, | ||
page?: number, | ||
searchQuery?: string, | ||
postStatusId?: number, | ||
): void; | ||
requestPostStatuses(): void; | ||
handleSearchFilterChange(searchQuery: string): void; | ||
handlePostStatusFilterChange(postStatusId: number): void; | ||
} | ||
|
||
class BoardP extends React.Component<Props> { | ||
searchFilterTimeoutId: ReturnType<typeof setTimeout>; | ||
|
||
componentDidMount() { | ||
this.props.requestPosts(this.props.board.id); | ||
this.props.requestPostStatuses(); | ||
} | ||
|
||
componentDidUpdate(prevProps) { | ||
const { searchQuery } = this.props.posts.filters; | ||
const prevSearchQuery = prevProps.posts.filters.searchQuery; | ||
|
||
const { postStatusId } = this.props.posts.filters; | ||
const prevPostStatusId = prevProps.posts.filters.postStatusId; | ||
|
||
// search filter changed | ||
if (searchQuery !== prevSearchQuery) { | ||
if (this.searchFilterTimeoutId) clearInterval(this.searchFilterTimeoutId); | ||
|
||
this.searchFilterTimeoutId = setTimeout(() => ( | ||
this.props.requestPosts(this.props.board.id, 1, searchQuery, postStatusId) | ||
), 500); | ||
} | ||
|
||
// post status filter changed | ||
if (postStatusId !== prevPostStatusId) { | ||
this.props.requestPosts(this.props.board.id, 1, searchQuery, postStatusId); | ||
} | ||
} | ||
|
||
render() { | ||
const { | ||
board, | ||
isLoggedIn, | ||
authenticityToken, | ||
posts, | ||
postStatuses, | ||
|
||
requestPosts, | ||
handleSearchFilterChange, | ||
handlePostStatusFilterChange, | ||
} = this.props; | ||
|
||
return ( | ||
<div className="boardContainer"> | ||
<div className="sidebar"> | ||
<NewPost | ||
board={board} | ||
isLoggedIn={isLoggedIn} | ||
authenticityToken={authenticityToken} | ||
/> | ||
<SearchFilter | ||
searchQuery={posts.filters.searchQuery} | ||
handleChange={handleSearchFilterChange} | ||
/> | ||
<PostStatusFilter | ||
postStatuses={postStatuses.items} | ||
areLoading={postStatuses.areLoading} | ||
error={postStatuses.error} | ||
|
||
currentFilter={posts.filters.postStatusId} | ||
handleFilterClick={handlePostStatusFilterChange} | ||
/> | ||
</div> | ||
|
||
<PostList | ||
posts={posts.items} | ||
postStatuses={postStatuses.items} | ||
page={posts.page} | ||
hasMore={posts.haveMore} | ||
areLoading={posts.areLoading} | ||
error={posts.error} | ||
|
||
handleLoadMore={() => requestPosts(board.id, posts.page + 1)} | ||
/> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default BoardP; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.