Skip to content

Commit

Permalink
feat: Add tags for GitHub integration FE (#4035)
Browse files Browse the repository at this point in the history
  • Loading branch information
novakzaballa authored Aug 12, 2024
1 parent 7920e8e commit 3c46a31
Show file tree
Hide file tree
Showing 12 changed files with 327 additions and 106 deletions.
1 change: 0 additions & 1 deletion frontend/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ export default {
),
'iOS': require('./code-help/traits/traits-ios')(envId, keywords, userId),
}),

keys: {
'Java': 'java',
'JavaScript': 'javascript',
Expand Down
2 changes: 1 addition & 1 deletion frontend/common/services/useGithubRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const githubRepositoryService = service
>({
invalidatesTags: [{ id: 'LIST', type: 'GithubRepository' }],
query: (query: Req['updateGithubRepository']) => ({
body: query,
body: query.body,
method: 'PUT',
url: `organisations/${query.organisation_id}/integrations/github/${query.github_id}/repositories/${query.id}/`,
}),
Expand Down
6 changes: 6 additions & 0 deletions frontend/common/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,12 @@ export type Req = {
organisation_id: string
github_id: string
id: string
body: {
project: number
repository_name: string
repository_owner: string
tagging_enabled: boolean
}
}
deleteGithubRepository: {
organisation_id: string
Expand Down
9 changes: 6 additions & 3 deletions frontend/common/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export type ExternalResource = {
url: string
type: string
project?: number
metadata?: { state?: string; title?: string }
metadata?: { [key: string]: string | number | boolean }
feature: number
}

Expand Down Expand Up @@ -160,12 +160,14 @@ export type LaunchDarklyProjectImport = {
project: number
}

export type GithubResources = {
export type GithubResource = {
html_url: string
id: number
number: number
title: string
state: string
merged: boolean
draft: boolean
}

export type GithubPaginatedRepos<T> = {
Expand All @@ -187,6 +189,7 @@ export type GithubRepository = {
project: number
repository_owner: string
repository_name: string
tagging_enabled: boolean
}

export type githubIntegration = {
Expand Down Expand Up @@ -685,7 +688,7 @@ export type Res = {
externalResource: PagedResponse<ExternalResource>
githubIntegrations: PagedResponse<githubIntegration>
githubRepository: PagedResponse<GithubRepository>
githubResources: GitHubPagedResponse<GithubResources>
githubResources: GitHubPagedResponse<GithubResource>
githubRepos: GithubPaginatedRepos<Repository>
segmentPriorities: {}
featureSegment: FeatureState['feature_segment']
Expand Down
8 changes: 6 additions & 2 deletions frontend/common/useInfiniteScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ const useInfiniteScroll = <
}, throttle)

const refresh = useCallback(() => {
setLocalPage(1)
}, [])
queryResponse.refetch().then((newData) => {
setCombinedData(newData as unknown as RES)
setLocalPage(1)
})
}, [queryResponse])

const loadMore = () => {
if (queryResponse?.data?.next) {
Expand All @@ -70,6 +73,7 @@ const useInfiniteScroll = <
isLoading: queryResponse.isLoading,
loadMore,
loadingCombinedData: loadingCombinedData && queryResponse.isFetching,
// refetchData,
refresh,
response: queryResponse,
searchItems,
Expand Down
61 changes: 40 additions & 21 deletions frontend/web/components/ExternalResourcesLinkTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,26 @@ import MyRepositoriesSelect from './MyRepositoriesSelect'
import ExternalResourcesTable, {
ExternalResourcesTableBase,
} from './ExternalResourcesTable'
import { ExternalResource } from 'common/types/responses'
import { ExternalResource, GithubResource } from 'common/types/responses'
import { GitHubResourceSelectProvider } from './GitHubResourceSelectProvider'
import { useCreateExternalResourceMutation } from 'common/services/useExternalResource'
import Constants from 'common/constants'
import Button from './base/forms/Button'
import GitHubResourcesSelect from './GitHubResourcesSelect'
import _ from 'lodash'
import AppActions from 'common/dispatcher/app-actions'

type ExternalResourcesLinkTabType = {
githubId: string
organisationId: string
featureId: string
projectId: string
environmentId: string
}

type AddExternalResourceRowType = ExternalResourcesTableBase & {
linkedExternalResources?: ExternalResource[]
environmentId: string
}

type GitHubStatusType = {
Expand All @@ -28,6 +31,7 @@ type GitHubStatusType = {
}

const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
environmentId,
featureId,
linkedExternalResources,
organisationId,
Expand All @@ -36,8 +40,9 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
repoOwner,
}) => {
const [externalResourceType, setExternalResourceType] = useState<string>('')
const [featureExternalResource, setFeatureExternalResource] =
useState<string>('')
const [featureExternalResource, setFeatureExternalResource] = useState<
GithubResource | undefined
>(undefined)
const [lastSavedResource, setLastSavedResource] = useState<
string | undefined
>(undefined)
Expand Down Expand Up @@ -68,11 +73,13 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
repoOwner={repoOwner}
repoName={repoName}
githubResource={
(
_.find(_.values(Constants.resourceTypes), {
label: externalResourceType!,
}) as any
).resourceType || ''
(externalResourceType &&
(
_.find(_.values(Constants.resourceTypes), {
label: externalResourceType!,
}) as any
).resourceType) ||
''
}
>
<GitHubResourcesSelect
Expand All @@ -94,19 +101,29 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
key as keyof typeof Constants.resourceTypes
].label === externalResourceType,
)
createExternalResource({
body: {
feature: parseInt(featureId),
metadata: {},
type: type!,
url: featureExternalResource,
},
feature_id: featureId,
project_id: projectId,
}).then(() => {
toast('External Resource Added')
setLastSavedResource(featureExternalResource)
})
if (type && featureExternalResource) {
createExternalResource({
body: {
feature: parseInt(featureId),
metadata: {
'draft': featureExternalResource.draft,
'merged': featureExternalResource.merged,
'state': featureExternalResource.state,
'title': featureExternalResource.title,
},
type: type,
url: featureExternalResource.html_url,
},
feature_id: featureId,
project_id: projectId,
}).then(() => {
toast('External Resource Added')
setLastSavedResource(featureExternalResource.html_url)
AppActions.refreshFeatures(parseInt(projectId), environmentId)
})
} else {
throw new Error('Invalid External Resource Data')
}
}}
>
Save
Expand All @@ -118,6 +135,7 @@ const AddExternalResourceRow: FC<AddExternalResourceRowType> = ({
}

const ExternalResourcesLinkTab: FC<ExternalResourcesLinkTabType> = ({
environmentId,
featureId,
githubId,
organisationId,
Expand Down Expand Up @@ -157,6 +175,7 @@ const ExternalResourcesLinkTab: FC<ExternalResourcesLinkTabType> = ({
/>
{repoName && repoOwner && (
<AddExternalResourceRow
environmentId={environmentId}
featureId={featureId}
projectId={projectId}
organisationId={organisationId}
Expand Down
11 changes: 7 additions & 4 deletions frontend/web/components/GitHubResourceSelectProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, useContext, FC, useEffect, useState } from 'react'
import { useGetGithubResourcesQuery } from 'common/services/useGithub'
import { ExternalResource, GithubResources, Res } from 'common/types/responses'
import { ExternalResource, GithubResource, Res } from 'common/types/responses'
import useInfiniteScroll from 'common/useInfiniteScroll'
import { Req } from 'common/types/requests'

Expand All @@ -17,13 +17,14 @@ type GitHubResourceSelectProviderType = {

type GitHubResourceSelectContextType = {
count: number
githubResources?: GithubResources[]
githubResources?: GithubResource[]
isFetching: boolean
isLoading: boolean
loadMore: () => void
loadingCombinedData: boolean
nextPage?: string
searchItems: (search: string) => void
refresh: () => void
}

const GitHubResourceSelectContext = createContext<
Expand All @@ -34,7 +35,7 @@ export const GitHubResourceSelectProvider: FC<
GitHubResourceSelectProviderType
> = ({ children, ...props }) => {
const [externalResourcesSelect, setExternalResourcesSelect] =
useState<GithubResources[]>()
useState<GithubResource[]>()

const throttleDelay = 300

Expand All @@ -44,6 +45,7 @@ export const GitHubResourceSelectProvider: FC<
isLoading,
loadMore,
loadingCombinedData,
refresh,
searchItems,
} = useInfiniteScroll<Req['getGithubResources'], Res['githubResources']>(
useGetGithubResourcesQuery,
Expand All @@ -62,7 +64,7 @@ export const GitHubResourceSelectProvider: FC<
useEffect(() => {
if (results && props.linkedExternalResources) {
setExternalResourcesSelect(
results.filter((i: GithubResources) => {
results.filter((i: GithubResource) => {
const same = props.linkedExternalResources?.some(
(r) => i.html_url === r.url,
)
Expand All @@ -84,6 +86,7 @@ export const GitHubResourceSelectProvider: FC<
loadMore,
loadingCombinedData,
nextPage: next,
refresh,
searchItems,
}}
>
Expand Down
40 changes: 27 additions & 13 deletions frontend/web/components/GitHubResourcesSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React, { FC, useEffect, useRef, useState } from 'react'
import { GithubResources } from 'common/types/responses'
import { GithubResource } from 'common/types/responses'
import Utils from 'common/utils/utils'
import { FixedSizeList } from 'react-window'
import InfiniteLoader from 'react-window-infinite-loader'
import { useGitHubResourceSelectProvider } from './GitHubResourceSelectProvider'
import { components } from 'react-select'
import Button from './base/forms/Button'
import Icon from './Icon'
import Select from 'react-select'

type MenuListType = {
children: React.ReactNode
Expand Down Expand Up @@ -106,6 +110,23 @@ const MenuList: FC<MenuListType> = ({
)
}

const CustomControl = ({
children,
...props
}: {
children: React.ReactNode
}) => {
const { refresh } = useGitHubResourceSelectProvider()
return (
<components.Control {...props}>
{children}
<Button style={{ marginLeft: 'auto' }} theme='icon' onClick={refresh}>
<Icon name='refresh' />
</Button>
</components.Control>
)
}

export type GitHubResourcesSelectType = {
onChange: (value: string) => void
lastSavedResource: string | undefined
Expand All @@ -119,15 +140,8 @@ const GitHubResourcesSelect: FC<GitHubResourcesSelectType> = ({
lastSavedResource,
onChange,
}) => {
const {
githubResources,
isFetching,
isLoading,
loadMore,
loadingCombinedData,
nextPage,
searchItems,
} = useGitHubResourceSelectProvider()
const { githubResources, isFetching, isLoading, searchItems } =
useGitHubResourceSelectProvider()
const [selectedOption, setSelectedOption] =
useState<GitHubResourcesValueType | null>(null)
const [searchText, setSearchText] = React.useState('')
Expand All @@ -152,11 +166,10 @@ const GitHubResourcesSelect: FC<GitHubResourcesSelectType> = ({
onChange(v?.value)
}}
isClearable={true}
options={githubResources?.map((i: GithubResources) => {
options={githubResources?.map((i: GithubResource) => {
return {
label: `${i.title} #${i.number}`,
status: i.state,
value: i.html_url,
value: i,
}
})}
noOptionsMessage={() =>
Expand All @@ -171,6 +184,7 @@ const GitHubResourcesSelect: FC<GitHubResourcesSelectType> = ({
searchItems(Utils.safeParseEventValue(e))
}}
components={{
Control: CustomControl,
MenuList,
}}
data={{ searchText }}
Expand Down
Loading

0 comments on commit 3c46a31

Please sign in to comment.