11import React from 'react' ;
22import { Query } from 'react-apollo' ;
3- import gql from 'graphql-tag ' ;
3+ import { withState } from 'recompose ' ;
44
5+ import { GET_ISSUES_OF_REPOSITORY } from './queries' ;
56import IssueItem from '../IssueItem' ;
67import Loading from '../../Loading' ;
78import ErrorMessage from '../../Error' ;
9+ import FetchMore from '../../FetchMore' ;
810import { ButtonUnobtrusive } from '../../Button' ;
911
1012import './style.css' ;
1113
12- const GET_ISSUES_OF_REPOSITORY = gql `
13- query($repositoryOwner: String!, $repositoryName: String!) {
14- repository(name: $repositoryName, owner: $repositoryOwner) {
15- issues(first: 5) {
16- edges {
17- node {
18- id
19- number
20- state
21- title
22- url
23- bodyHTML
24- }
25- }
26- }
27- }
28- }
29- ` ;
30-
3114const ISSUE_STATES = {
3215 NONE : 'NONE' ,
3316 OPEN : 'OPEN' ,
@@ -48,75 +31,121 @@ const TRANSITION_STATE = {
4831
4932const isShow = issueState => issueState !== ISSUE_STATES . NONE ;
5033
51- class Issues extends React . Component {
52- state = {
53- issueState : ISSUE_STATES . NONE ,
54- } ;
34+ const updateQuery = ( previousResult , { fetchMoreResult } ) => {
35+ if ( ! fetchMoreResult ) {
36+ return previousResult ;
37+ }
5538
56- onChangeIssueState = nextIssueState => {
57- this . setState ( { issueState : nextIssueState } ) ;
39+ return {
40+ ...previousResult ,
41+ repository : {
42+ ...previousResult . repository ,
43+ issues : {
44+ ...previousResult . repository . issues ,
45+ ...fetchMoreResult . repository . issues ,
46+ edges : [
47+ ...previousResult . repository . issues . edges ,
48+ ...fetchMoreResult . repository . issues . edges ,
49+ ] ,
50+ } ,
51+ } ,
5852 } ;
53+ } ;
54+
55+ const Issues = ( {
56+ repositoryOwner,
57+ repositoryName,
58+ issueState,
59+ onChangeIssueState,
60+ } ) => (
61+ < div className = "Issues" >
62+ < ButtonUnobtrusive
63+ onClick = { ( ) => onChangeIssueState ( TRANSITION_STATE [ issueState ] ) }
64+ >
65+ { TRANSITION_LABELS [ issueState ] }
66+ </ ButtonUnobtrusive >
67+
68+ { isShow ( issueState ) && (
69+ < Query
70+ query = { GET_ISSUES_OF_REPOSITORY }
71+ variables = { {
72+ repositoryOwner,
73+ repositoryName,
74+ issueState,
75+ } }
76+ notifyOnNetworkStatusChange = { true }
77+ >
78+ { ( { data, loading, error, fetchMore } ) => {
79+ if ( error ) {
80+ return < ErrorMessage error = { error } /> ;
81+ }
5982
60- render ( ) {
61- const { issueState } = this . state ;
62- const { repositoryOwner, repositoryName } = this . props ;
83+ const { repository } = data ;
6384
64- return (
65- < div className = "Issues" >
66- < ButtonUnobtrusive
67- onClick = { ( ) =>
68- this . onChangeIssueState ( TRANSITION_STATE [ issueState ] )
85+ if ( loading && ! repository ) {
86+ return < Loading /> ;
87+ }
88+
89+ const filteredRepository = {
90+ issues : {
91+ edges : repository . issues . edges . filter (
92+ issue => issue . node . state === issueState ,
93+ ) ,
94+ } ,
95+ } ;
96+
97+ if ( ! filteredRepository . issues . edges . length ) {
98+ return < div className = "IssueList" > No issues ...</ div > ;
6999 }
70- >
71- { TRANSITION_LABELS [ issueState ] }
72- </ ButtonUnobtrusive >
73-
74- { isShow ( issueState ) && (
75- < Query
76- query = { GET_ISSUES_OF_REPOSITORY }
77- variables = { {
78- repositoryOwner,
79- repositoryName,
80- } }
81- >
82- { ( { data, loading, error } ) => {
83- if ( error ) {
84- return < ErrorMessage error = { error } /> ;
85- }
86-
87- const { repository } = data ;
88-
89- if ( loading && ! repository ) {
90- return < Loading /> ;
91- }
92-
93- const filteredRepository = {
94- issues : {
95- edges : repository . issues . edges . filter (
96- issue => issue . node . state === issueState ,
97- ) ,
98- } ,
99- } ;
100-
101- if ( ! filteredRepository . issues . edges . length ) {
102- return < div className = "IssueList" > No issues ...</ div > ;
103- }
104-
105- return < IssueList issues = { filteredRepository . issues } /> ;
106- } }
107- </ Query >
108- ) }
109- </ div >
110- ) ;
111- }
112- }
113100
114- const IssueList = ( { issues } ) => (
101+ return (
102+ < IssueList
103+ issues = { repository . issues }
104+ loading = { loading }
105+ repositoryOwner = { repositoryOwner }
106+ repositoryName = { repositoryName }
107+ issueState = { issueState }
108+ fetchMore = { fetchMore }
109+ />
110+ ) ;
111+ } }
112+ </ Query >
113+ ) }
114+ </ div >
115+ ) ;
116+
117+ const IssueList = ( {
118+ issues,
119+ loading,
120+ repositoryOwner,
121+ repositoryName,
122+ issueState,
123+ fetchMore,
124+ } ) => (
115125 < div className = "IssueList" >
116126 { issues . edges . map ( ( { node } ) => (
117127 < IssueItem key = { node . id } issue = { node } />
118128 ) ) }
129+
130+ < FetchMore
131+ loading = { loading }
132+ hasNextPage = { issues . pageInfo . hasNextPage }
133+ variables = { {
134+ cursor : issues . pageInfo . endCursor ,
135+ repositoryOwner,
136+ repositoryName,
137+ issueState,
138+ } }
139+ updateQuery = { updateQuery }
140+ fetchMore = { fetchMore }
141+ >
142+ Issues
143+ </ FetchMore >
119144 </ div >
120145) ;
121146
122- export default Issues ;
147+ export default withState (
148+ 'issueState' ,
149+ 'onChangeIssueState' ,
150+ ISSUE_STATES . NONE ,
151+ ) ( Issues ) ;
0 commit comments