1
1
import { Cross1Icon , InfoCircledIcon , WidthIcon } from "@radix-ui/react-icons" ;
2
- import React , { useContext , useState } from "react" ;
2
+ import React , { useContext , useEffect , useState } from "react" ;
3
3
import { LINEAR } from "../utils/constants" ;
4
4
import { updateGitHubWebhook } from "../utils/github" ;
5
- import { updateLinearWebhook } from "../utils/linear" ;
5
+ import { getLinearWebhook , updateLinearWebhook } from "../utils/linear" ;
6
6
import { Context } from "./ContextProvider" ;
7
7
import Tooltip from "./Tooltip" ;
8
8
9
+ const options = [ "Cycle" , "Project" ] as const ;
10
+ type Option = ( typeof options ) [ number ] ;
11
+
9
12
const Dashboard = ( ) => {
10
13
const { syncs, setSyncs, gitHubContext, linearContext } =
11
14
useContext ( Context ) ;
12
15
13
16
const [ loading , setLoading ] = useState ( false ) ;
17
+ const [ milestoneAction , setMilestoneAction ] = useState < Option | null > ( null ) ;
18
+
19
+ // Get initial webhook settings
20
+ useEffect ( ( ) => {
21
+ if ( ! syncs ?. length ) return ;
22
+
23
+ getLinearWebhook (
24
+ linearContext . apiKey ,
25
+ syncs [ 0 ] . LinearTeam . teamName
26
+ ) . then ( res => {
27
+ if ( res . resourceTypes . includes ( "Cycle" ) ) {
28
+ setMilestoneAction ( "Cycle" ) ;
29
+ } else if ( res . resourceTypes . includes ( "Project" ) ) {
30
+ setMilestoneAction ( "Project" ) ;
31
+ }
32
+ } ) ;
33
+ } , [ syncs ] ) ;
14
34
15
35
const removeSync = async ( syncId : string ) => {
16
36
if ( ! syncId || ! gitHubContext . apiKey ) return ;
@@ -37,36 +57,37 @@ const Dashboard = () => {
37
57
} ) ;
38
58
} ;
39
59
40
- const handleMilestoneSyncChange = async (
41
- e : React . ChangeEvent < HTMLInputElement >
42
- ) => {
43
- setLoading ( true ) ;
60
+ useEffect ( ( ) => {
61
+ const handleMilestoneSyncChange = async ( ) => {
62
+ setLoading ( true ) ;
44
63
45
- const checked = e . target . checked || false ;
64
+ for ( const sync of syncs ) {
65
+ await updateGitHubWebhook (
66
+ gitHubContext . apiKey ,
67
+ sync . GitHubRepo . repoName ,
68
+ {
69
+ ...( milestoneAction
70
+ ? { add_events : [ "milestone" ] }
71
+ : { remove_events : [ "milestone" ] } )
72
+ }
73
+ ) ;
74
+ await updateLinearWebhook (
75
+ linearContext . apiKey ,
76
+ sync . LinearTeam . teamName ,
77
+ {
78
+ resourceTypes : [
79
+ ...LINEAR . WEBHOOK_EVENTS ,
80
+ ...( milestoneAction ? [ milestoneAction ] : [ ] )
81
+ ]
82
+ }
83
+ ) ;
84
+ }
46
85
47
- for ( const sync of syncs ) {
48
- await updateGitHubWebhook (
49
- gitHubContext . apiKey ,
50
- sync . GitHubRepo . repoName ,
51
- {
52
- ...( checked && { add_events : [ "milestone" ] } ) ,
53
- ...( ! checked && { remove_events : [ "milestone" ] } )
54
- }
55
- ) ;
56
- await updateLinearWebhook (
57
- linearContext . apiKey ,
58
- sync . LinearTeam . teamName ,
59
- {
60
- resourceTypes : [
61
- ...LINEAR . WEBHOOK_EVENTS ,
62
- ...( checked ? [ "Cycle" ] : [ ] )
63
- ]
64
- }
65
- ) ;
66
- }
86
+ setLoading ( false ) ;
87
+ } ;
67
88
68
- setLoading ( false ) ;
69
- } ;
89
+ handleMilestoneSyncChange ( ) ;
90
+ } , [ milestoneAction ] ) ;
70
91
71
92
if ( ! syncs ?. length ) return < > </ > ;
72
93
@@ -104,19 +125,45 @@ const Dashboard = () => {
104
125
</ Tooltip >
105
126
</ div >
106
127
) ) }
107
- < div className = "flex items-center space-x-2 mb-4" >
108
- < input
109
- disabled = { ! linearContext . apiKey }
110
- type = "checkbox"
111
- id = "syncsMilestones"
112
- onChange = { handleMilestoneSyncChange }
113
- />
114
- < label htmlFor = "syncsMilestones" className = "whitespace-nowrap" >
115
- Sync milestones to cycles
116
- </ label >
117
- < Tooltip content = "Requires connecting to Linear first" >
118
- < InfoCircledIcon className = "w-6 h-6 text-gray-400 hover:font-secondary transition-colors duration-200" />
119
- </ Tooltip >
128
+ < div className = "flex flex-col items-start" >
129
+ { options . map ( option => (
130
+ < div
131
+ key = { option }
132
+ className = "flex items-center space-x-2 mb-4"
133
+ >
134
+ < input
135
+ id = { option }
136
+ disabled = { ! linearContext . apiKey }
137
+ type = "checkbox"
138
+ checked = { milestoneAction === option }
139
+ onChange = { e =>
140
+ setMilestoneAction (
141
+ e . target . checked
142
+ ? ( e . target . id as Option )
143
+ : null
144
+ )
145
+ }
146
+ />
147
+ < label htmlFor = { option } className = "whitespace-nowrap" >
148
+ Sync { option } s to Milestones
149
+ </ label >
150
+ < Tooltip
151
+ content = {
152
+ ! linearContext . apiKey
153
+ ? "Requires connecting to Linear first"
154
+ : milestoneAction
155
+ ? `Will disable ${
156
+ option == "Cycle"
157
+ ? "Project"
158
+ : "Cycle"
159
+ } sync`
160
+ : ""
161
+ }
162
+ >
163
+ < InfoCircledIcon className = "w-6 h-6 text-gray-400 hover:font-secondary transition-colors duration-200" />
164
+ </ Tooltip >
165
+ </ div >
166
+ ) ) }
120
167
</ div >
121
168
</ div >
122
169
) ;
0 commit comments