1
- import React , { useState } from 'react' ;
1
+ import React , { useEffect , useState } from 'react' ;
2
2
import cn from 'classnames' ;
3
3
4
- import { closeMergeRequest , mergeMergeRequest , allowMerge } from './services' ;
4
+ import {
5
+ getMergeRequestDetail ,
6
+ closeMergeRequest ,
7
+ mergeMergeRequest ,
8
+ allowMerge ,
9
+ disallowMerge ,
10
+ getReviewers
11
+ } from './services' ;
5
12
import { MERGE_STATUS_TEXT , MERGE_STATUS } from './constants' ;
6
13
import style from './style.css' ;
7
14
@@ -14,20 +21,58 @@ const toast = (msg: string) => {
14
21
15
22
const App = ( ) => {
16
23
const data = JSON . parse ( window . __CODING__ ) ;
17
- const { session, mrItem , repoInfo } = data ;
24
+ const { session, repoInfo , mergeRequestIId } = data ;
18
25
const { accessToken } = session ;
19
26
const user = session ?. user ;
20
27
const team = user ?. team ;
21
28
22
- const { can_merge : canMerge , merge_request : mergeRequest } = mrItem ;
23
- const { title, srcBranch, desBranch, author, merge_status : mergeStatus } = mergeRequest ;
24
- const url = `https://${ team } .coding.net${ mergeRequest . path } ` ;
25
-
26
29
const [ isClosing , setIsClosing ] = useState ( false ) ;
27
30
const [ isMerging , setIsMerging ] = useState ( false ) ;
28
31
const [ isAllowing , setIsAllowing ] = useState ( false ) ;
29
- const [ mrStatus , setMrStatus ] = useState ( mergeStatus ) ;
30
- const [ allowText , setAllowText ] = useState ( '允许合并' ) ;
32
+ const [ isDisAllowing , setIsDisAllowing ] = useState ( false ) ;
33
+ const [ mrStatus , setMrStatus ] = useState < MERGE_STATUS > ( MERGE_STATUS . CANMERGE ) ;
34
+ const [ mrDetail , setMrDetail ] = useState ( ) ;
35
+ const [ reviewers , setReviewers ] = useState < { reviewers : any [ ] , volunteer_reviewers : any [ ] } > ( { reviewers : [ ] , volunteer_reviewers : [ ] } ) ;
36
+
37
+ const index = reviewers . reviewers . findIndex ( ( r ) => r . reviewer . id === user . id ) ;
38
+ let agreed = true ;
39
+ if ( index >= 0 ) {
40
+ agreed = reviewers . reviewers [ index ] . value === 100 ;
41
+ } else {
42
+ agreed = reviewers . volunteer_reviewers . findIndex ( ( r ) => r . reviewer . id === user . id ) >= 0 ;
43
+ }
44
+
45
+ const [ isAgreed , setIsAgreed ] = useState ( agreed ) ;
46
+
47
+ const getParams = ( ) => ( {
48
+ ...repoInfo ,
49
+ mergeRequestIId
50
+ } ) ;
51
+
52
+ useEffect ( ( ) => {
53
+ const asyncFn = async ( ) => {
54
+ const [ detailRes , reviewersRes ] = await Promise . all ( [
55
+ getMergeRequestDetail ( accessToken , { ...getParams ( ) } ) ,
56
+ getReviewers ( accessToken , { ...getParams ( ) } )
57
+ ] ) ;
58
+
59
+ if ( ! reviewersRes . code ) {
60
+ setReviewers ( reviewersRes . data ) ;
61
+ }
62
+
63
+ if ( ! detailRes . code ) {
64
+ setMrDetail ( detailRes . data ) ;
65
+ setMrStatus ( detailRes . data . merge_request . merge_status ) ;
66
+ }
67
+ } ;
68
+ asyncFn ( ) ;
69
+ } , [ ] ) ;
70
+
71
+ if ( ! mrDetail ) return null ;
72
+
73
+ const { can_merge : canMerge , merge_request : mergeRequest } = mrDetail as any ;
74
+ const { title, srcBranch, desBranch, author, body } = mergeRequest ;
75
+ const url = `https://${ team } .coding.net${ mergeRequest . path } ` ;
31
76
32
77
const viewOnWeb = ( ) => {
33
78
window . hbuilderx . postMessage ( {
@@ -40,10 +85,7 @@ const App = () => {
40
85
if ( isClosing ) return ;
41
86
42
87
setIsClosing ( true ) ;
43
- const result = await closeMergeRequest ( accessToken , {
44
- ...repoInfo ,
45
- mergeRequestIId : mergeRequest . iid
46
- } ) ;
88
+ const result = await closeMergeRequest ( accessToken , { ...getParams ( ) } ) ;
47
89
48
90
if ( ! result . code ) {
49
91
setMrStatus ( MERGE_STATUS . REFUSED ) ;
@@ -59,8 +101,7 @@ const App = () => {
59
101
60
102
setIsMerging ( true ) ;
61
103
const result = await mergeMergeRequest ( accessToken , {
62
- ...repoInfo ,
63
- mergeRequestIId : mergeRequest . iid ,
104
+ ...getParams ( ) ,
64
105
message : `
65
106
Accept Merge Request #${ mergeRequest . iid } : (${ srcBranch } -> ${ desBranch } )
66
107
Merge Request: ${ title }
@@ -83,20 +124,32 @@ const App = () => {
83
124
if ( isAllowing ) return ;
84
125
85
126
setIsAllowing ( true ) ;
86
- const result = await allowMerge ( accessToken , {
87
- ...repoInfo ,
88
- mergeRequestIId : mergeRequest . iid
89
- } ) ;
127
+ const result = await allowMerge ( accessToken , { ...getParams ( ) } ) ;
90
128
91
129
if ( ! result . code ) {
92
- setAllowText ( '已允许' ) ;
130
+ setIsAgreed ( true ) ;
93
131
} else {
94
132
toast ( '操作失败' ) ;
95
133
}
96
134
97
135
setIsAllowing ( false ) ;
98
136
} ;
99
137
138
+ const handleDisAllowMerge = async ( ) => {
139
+ if ( isDisAllowing ) return ;
140
+
141
+ setIsDisAllowing ( true ) ;
142
+ const result = await disallowMerge ( accessToken , { ...getParams ( ) } ) ;
143
+
144
+ if ( ! result . code ) {
145
+ setIsAgreed ( false ) ;
146
+ } else {
147
+ toast ( '操作失败' ) ;
148
+ }
149
+
150
+ setIsDisAllowing ( false ) ;
151
+ } ;
152
+
100
153
const renderStatus = ( ) => {
101
154
const CNS = {
102
155
[ MERGE_STATUS . CANMERGE ] : style . success ,
@@ -106,6 +159,8 @@ const App = () => {
106
159
return < span className = { cn ( style . status , CNS [ mrStatus ] ) } > { MERGE_STATUS_TEXT [ mrStatus ] } </ span > ;
107
160
} ;
108
161
162
+ const renderActionText = ( loading : boolean , text : string ) => loading ? `${ text } 中...` : text ;
163
+
109
164
const showCloseBtn = ( canMerge || user . id === mergeRequest . author . id ) && mrStatus !== MERGE_STATUS . REFUSED && mrStatus !== MERGE_STATUS . ACCEPTED ;
110
165
const mrStatusOk = mrStatus === MERGE_STATUS . CANMERGE || mrStatus === MERGE_STATUS . CANNOTMERGE ;
111
166
const showMergeBtn = mrStatus === MERGE_STATUS . CANMERGE ;
@@ -121,22 +176,34 @@ const App = () => {
121
176
< div > { `将分支 ${ srcBranch } 合并到分支 ${ desBranch } ` } </ div >
122
177
< div > 创建人:{ author . name } </ div >
123
178
179
+ < h3 > 概览:</ h3 >
180
+ < div dangerouslySetInnerHTML = { { __html : body } } />
181
+
124
182
< div className = { style . btnGroup } >
125
183
{ showMergeBtn && (
126
184
< div
127
185
className = { cn ( style . btn , style . btnPrimary , isMerging && style . disabled ) }
128
186
onClick = { handleMerge }
129
187
>
130
- { isMerging ? '合并中...' : ' 合并'}
188
+ { renderActionText ( isMerging , ' 合并') }
131
189
</ div >
132
190
) }
133
191
134
- { showAllowMergeBtn && (
192
+ { showAllowMergeBtn && ! isAgreed && (
135
193
< div
136
194
className = { cn ( style . btn , style . btnPrimary , isAllowing && style . disabled ) }
137
195
onClick = { handleAllowMerge }
138
196
>
139
- { allowText }
197
+ { renderActionText ( isAllowing , '允许合并' ) }
198
+ </ div >
199
+ ) }
200
+
201
+ { showAllowMergeBtn && isAgreed && (
202
+ < div
203
+ className = { cn ( style . btn , style . btnPrimary , isDisAllowing && style . disabled ) }
204
+ onClick = { handleDisAllowMerge }
205
+ >
206
+ { renderActionText ( isDisAllowing , '撤销允许合并' ) }
140
207
</ div >
141
208
) }
142
209
@@ -145,7 +212,7 @@ const App = () => {
145
212
className = { cn ( style . btn , isClosing && style . disabled ) }
146
213
onClick = { handleClose }
147
214
>
148
- { isClosing ? '关闭中...' : ' 关闭'}
215
+ { renderActionText ( isClosing , ' 关闭') }
149
216
</ div >
150
217
) }
151
218
</ div >
0 commit comments