Skip to content

Commit 3c46a31

Browse files
authored
feat: Add tags for GitHub integration FE (#4035)
1 parent 7920e8e commit 3c46a31

12 files changed

+327
-106
lines changed

frontend/common/constants.ts

-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ export default {
228228
),
229229
'iOS': require('./code-help/traits/traits-ios')(envId, keywords, userId),
230230
}),
231-
232231
keys: {
233232
'Java': 'java',
234233
'JavaScript': 'javascript',

frontend/common/services/useGithubRepository.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const githubRepositoryService = service
4343
>({
4444
invalidatesTags: [{ id: 'LIST', type: 'GithubRepository' }],
4545
query: (query: Req['updateGithubRepository']) => ({
46-
body: query,
46+
body: query.body,
4747
method: 'PUT',
4848
url: `organisations/${query.organisation_id}/integrations/github/${query.github_id}/repositories/${query.id}/`,
4949
}),

frontend/common/types/requests.ts

+6
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,12 @@ export type Req = {
397397
organisation_id: string
398398
github_id: string
399399
id: string
400+
body: {
401+
project: number
402+
repository_name: string
403+
repository_owner: string
404+
tagging_enabled: boolean
405+
}
400406
}
401407
deleteGithubRepository: {
402408
organisation_id: string

frontend/common/types/responses.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export type ExternalResource = {
115115
url: string
116116
type: string
117117
project?: number
118-
metadata?: { state?: string; title?: string }
118+
metadata?: { [key: string]: string | number | boolean }
119119
feature: number
120120
}
121121

@@ -160,12 +160,14 @@ export type LaunchDarklyProjectImport = {
160160
project: number
161161
}
162162

163-
export type GithubResources = {
163+
export type GithubResource = {
164164
html_url: string
165165
id: number
166166
number: number
167167
title: string
168168
state: string
169+
merged: boolean
170+
draft: boolean
169171
}
170172

171173
export type GithubPaginatedRepos<T> = {
@@ -187,6 +189,7 @@ export type GithubRepository = {
187189
project: number
188190
repository_owner: string
189191
repository_name: string
192+
tagging_enabled: boolean
190193
}
191194

192195
export type githubIntegration = {
@@ -685,7 +688,7 @@ export type Res = {
685688
externalResource: PagedResponse<ExternalResource>
686689
githubIntegrations: PagedResponse<githubIntegration>
687690
githubRepository: PagedResponse<GithubRepository>
688-
githubResources: GitHubPagedResponse<GithubResources>
691+
githubResources: GitHubPagedResponse<GithubResource>
689692
githubRepos: GithubPaginatedRepos<Repository>
690693
segmentPriorities: {}
691694
featureSegment: FeatureState['feature_segment']

frontend/common/useInfiniteScroll.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ const useInfiniteScroll = <
5555
}, throttle)
5656

5757
const refresh = useCallback(() => {
58-
setLocalPage(1)
59-
}, [])
58+
queryResponse.refetch().then((newData) => {
59+
setCombinedData(newData as unknown as RES)
60+
setLocalPage(1)
61+
})
62+
}, [queryResponse])
6063

6164
const loadMore = () => {
6265
if (queryResponse?.data?.next) {
@@ -70,6 +73,7 @@ const useInfiniteScroll = <
7073
isLoading: queryResponse.isLoading,
7174
loadMore,
7275
loadingCombinedData: loadingCombinedData && queryResponse.isFetching,
76+
// refetchData,
7377
refresh,
7478
response: queryResponse,
7579
searchItems,

frontend/web/components/ExternalResourcesLinkTab.tsx

+40-21
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@ import MyRepositoriesSelect from './MyRepositoriesSelect'
33
import ExternalResourcesTable, {
44
ExternalResourcesTableBase,
55
} from './ExternalResourcesTable'
6-
import { ExternalResource } from 'common/types/responses'
6+
import { ExternalResource, GithubResource } from 'common/types/responses'
77
import { GitHubResourceSelectProvider } from './GitHubResourceSelectProvider'
88
import { useCreateExternalResourceMutation } from 'common/services/useExternalResource'
99
import Constants from 'common/constants'
1010
import Button from './base/forms/Button'
1111
import GitHubResourcesSelect from './GitHubResourcesSelect'
1212
import _ from 'lodash'
13+
import AppActions from 'common/dispatcher/app-actions'
1314

1415
type ExternalResourcesLinkTabType = {
1516
githubId: string
1617
organisationId: string
1718
featureId: string
1819
projectId: string
20+
environmentId: string
1921
}
2022

2123
type AddExternalResourceRowType = ExternalResourcesTableBase & {
2224
linkedExternalResources?: ExternalResource[]
25+
environmentId: string
2326
}
2427

2528
type GitHubStatusType = {
@@ -28,6 +31,7 @@ type GitHubStatusType = {
2831
}
2932

3033
const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
34+
environmentId,
3135
featureId,
3236
linkedExternalResources,
3337
organisationId,
@@ -36,8 +40,9 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
3640
repoOwner,
3741
}) => {
3842
const [externalResourceType, setExternalResourceType] = useState<string>('')
39-
const [featureExternalResource, setFeatureExternalResource] =
40-
useState<string>('')
43+
const [featureExternalResource, setFeatureExternalResource] = useState<
44+
GithubResource | undefined
45+
>(undefined)
4146
const [lastSavedResource, setLastSavedResource] = useState<
4247
string | undefined
4348
>(undefined)
@@ -68,11 +73,13 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
6873
repoOwner={repoOwner}
6974
repoName={repoName}
7075
githubResource={
71-
(
72-
_.find(_.values(Constants.resourceTypes), {
73-
label: externalResourceType!,
74-
}) as any
75-
).resourceType || ''
76+
(externalResourceType &&
77+
(
78+
_.find(_.values(Constants.resourceTypes), {
79+
label: externalResourceType!,
80+
}) as any
81+
).resourceType) ||
82+
''
7683
}
7784
>
7885
<GitHubResourcesSelect
@@ -94,19 +101,29 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
94101
key as keyof typeof Constants.resourceTypes
95102
].label === externalResourceType,
96103
)
97-
createExternalResource({
98-
body: {
99-
feature: parseInt(featureId),
100-
metadata: {},
101-
type: type!,
102-
url: featureExternalResource,
103-
},
104-
feature_id: featureId,
105-
project_id: projectId,
106-
}).then(() => {
107-
toast('External Resource Added')
108-
setLastSavedResource(featureExternalResource)
109-
})
104+
if (type && featureExternalResource) {
105+
createExternalResource({
106+
body: {
107+
feature: parseInt(featureId),
108+
metadata: {
109+
'draft': featureExternalResource.draft,
110+
'merged': featureExternalResource.merged,
111+
'state': featureExternalResource.state,
112+
'title': featureExternalResource.title,
113+
},
114+
type: type,
115+
url: featureExternalResource.html_url,
116+
},
117+
feature_id: featureId,
118+
project_id: projectId,
119+
}).then(() => {
120+
toast('External Resource Added')
121+
setLastSavedResource(featureExternalResource.html_url)
122+
AppActions.refreshFeatures(parseInt(projectId), environmentId)
123+
})
124+
} else {
125+
throw new Error('Invalid External Resource Data')
126+
}
110127
}}
111128
>
112129
Save
@@ -118,6 +135,7 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
118135
}
119136

120137
const ExternalResourcesLinkTab: FC<ExternalResourcesLinkTabType> = ({
138+
environmentId,
121139
featureId,
122140
githubId,
123141
organisationId,
@@ -157,6 +175,7 @@ const ExternalResourcesLinkTab: FC<ExternalResourcesLinkTabType> = ({
157175
/>
158176
{repoName && repoOwner && (
159177
<AddExternalResourceRow
178+
environmentId={environmentId}
160179
featureId={featureId}
161180
projectId={projectId}
162181
organisationId={organisationId}

frontend/web/components/GitHubResourceSelectProvider.tsx

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createContext, useContext, FC, useEffect, useState } from 'react'
22
import { useGetGithubResourcesQuery } from 'common/services/useGithub'
3-
import { ExternalResource, GithubResources, Res } from 'common/types/responses'
3+
import { ExternalResource, GithubResource, Res } from 'common/types/responses'
44
import useInfiniteScroll from 'common/useInfiniteScroll'
55
import { Req } from 'common/types/requests'
66

@@ -17,13 +17,14 @@ type GitHubResourceSelectProviderType = {
1717

1818
type GitHubResourceSelectContextType = {
1919
count: number
20-
githubResources?: GithubResources[]
20+
githubResources?: GithubResource[]
2121
isFetching: boolean
2222
isLoading: boolean
2323
loadMore: () => void
2424
loadingCombinedData: boolean
2525
nextPage?: string
2626
searchItems: (search: string) => void
27+
refresh: () => void
2728
}
2829

2930
const GitHubResourceSelectContext = createContext<
@@ -34,7 +35,7 @@ export const GitHubResourceSelectProvider: FC<
3435
GitHubResourceSelectProviderType
3536
> = ({ children, ...props }) => {
3637
const [externalResourcesSelect, setExternalResourcesSelect] =
37-
useState<GithubResources[]>()
38+
useState<GithubResource[]>()
3839

3940
const throttleDelay = 300
4041

@@ -44,6 +45,7 @@ export const GitHubResourceSelectProvider: FC<
4445
isLoading,
4546
loadMore,
4647
loadingCombinedData,
48+
refresh,
4749
searchItems,
4850
} = useInfiniteScroll<Req['getGithubResources'], Res['githubResources']>(
4951
useGetGithubResourcesQuery,
@@ -62,7 +64,7 @@ export const GitHubResourceSelectProvider: FC<
6264
useEffect(() => {
6365
if (results && props.linkedExternalResources) {
6466
setExternalResourcesSelect(
65-
results.filter((i: GithubResources) => {
67+
results.filter((i: GithubResource) => {
6668
const same = props.linkedExternalResources?.some(
6769
(r) => i.html_url === r.url,
6870
)
@@ -84,6 +86,7 @@ export const GitHubResourceSelectProvider: FC<
8486
loadMore,
8587
loadingCombinedData,
8688
nextPage: next,
89+
refresh,
8790
searchItems,
8891
}}
8992
>

frontend/web/components/GitHubResourcesSelect.tsx

+27-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import React, { FC, useEffect, useRef, useState } from 'react'
2-
import { GithubResources } from 'common/types/responses'
2+
import { GithubResource } from 'common/types/responses'
33
import Utils from 'common/utils/utils'
44
import { FixedSizeList } from 'react-window'
55
import InfiniteLoader from 'react-window-infinite-loader'
66
import { useGitHubResourceSelectProvider } from './GitHubResourceSelectProvider'
7+
import { components } from 'react-select'
8+
import Button from './base/forms/Button'
9+
import Icon from './Icon'
10+
import Select from 'react-select'
711

812
type MenuListType = {
913
children: React.ReactNode
@@ -106,6 +110,23 @@ const MenuList: FC<MenuListType> = ({
106110
)
107111
}
108112

113+
const CustomControl = ({
114+
children,
115+
...props
116+
}: {
117+
children: React.ReactNode
118+
}) => {
119+
const { refresh } = useGitHubResourceSelectProvider()
120+
return (
121+
<components.Control {...props}>
122+
{children}
123+
<Button style={{ marginLeft: 'auto' }} theme='icon' onClick={refresh}>
124+
<Icon name='refresh' />
125+
</Button>
126+
</components.Control>
127+
)
128+
}
129+
109130
export type GitHubResourcesSelectType = {
110131
onChange: (value: string) => void
111132
lastSavedResource: string | undefined
@@ -119,15 +140,8 @@ const GitHubResourcesSelect: FC<GitHubResourcesSelectType> = ({
119140
lastSavedResource,
120141
onChange,
121142
}) => {
122-
const {
123-
githubResources,
124-
isFetching,
125-
isLoading,
126-
loadMore,
127-
loadingCombinedData,
128-
nextPage,
129-
searchItems,
130-
} = useGitHubResourceSelectProvider()
143+
const { githubResources, isFetching, isLoading, searchItems } =
144+
useGitHubResourceSelectProvider()
131145
const [selectedOption, setSelectedOption] =
132146
useState<GitHubResourcesValueType | null>(null)
133147
const [searchText, setSearchText] = React.useState('')
@@ -152,11 +166,10 @@ const GitHubResourcesSelect: FC<GitHubResourcesSelectType> = ({
152166
onChange(v?.value)
153167
}}
154168
isClearable={true}
155-
options={githubResources?.map((i: GithubResources) => {
169+
options={githubResources?.map((i: GithubResource) => {
156170
return {
157171
label: `${i.title} #${i.number}`,
158-
status: i.state,
159-
value: i.html_url,
172+
value: i,
160173
}
161174
})}
162175
noOptionsMessage={() =>
@@ -171,6 +184,7 @@ const GitHubResourcesSelect: FC<GitHubResourcesSelectType> = ({
171184
searchItems(Utils.safeParseEventValue(e))
172185
}}
173186
components={{
187+
Control: CustomControl,
174188
MenuList,
175189
}}
176190
data={{ searchText }}

0 commit comments

Comments
 (0)