Skip to content

Commit

Permalink
feat: Enable connecting to different GitLab integration providers (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
Dschoordsch authored Sep 10, 2024
1 parent 4368c0b commit 8806839
Show file tree
Hide file tree
Showing 55 changed files with 1,008 additions and 259 deletions.
2 changes: 2 additions & 0 deletions codegen.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"SetSlackNotificationPayload": "./types/SetSlackNotificationPayload#SetSlackNotificationPayloadSource",
"SetDefaultSlackChannelSuccess": "./types/SetDefaultSlackChannelSuccess#SetDefaultSlackChannelSuccessSource",
"AddCommentSuccess": "./types/AddCommentSuccess#AddCommentSuccessSource",
"AddIntegrationProviderSuccess": "./types/AddIntegrationProviderSuccess#AddIntegrationProviderSuccessSource",
"DeleteCommentSuccess": "./types/DeleteCommentSuccess#DeleteCommentSuccessSource",
"UpdateCommentContentSuccess": "./types/UpdateCommentContentSuccess#UpdateCommentContentSuccessSource",
"AddSlackAuthPayload": "./types/AddSlackAuthPayload#AddSlackAuthPayloadSource",
Expand Down Expand Up @@ -134,6 +135,7 @@
"TemplateScale": "../../postgres/types/index#TemplateScale as TemplateScaleDB",
"TemplateScaleRef": "../../postgres/types/index#TemplateScaleRef as TemplateScaleRefDB",
"Threadable": "./types/Threadable#ThreadableSource",
"OrgIntegrationProviders": "./types/OrgIntegrationProviders#OrgIntegrationProvidersSource",
"OrganizationUser": "../../postgres/types/index#OrganizationUser as OrganizationUserDB",
"PokerMeeting": "../../database/types/MeetingPoker#default as MeetingPoker",
"PokerMeetingMember": "../../database/types/MeetingPokerMeetingMember#default as PokerMeetingMemberDB",
Expand Down
6 changes: 6 additions & 0 deletions packages/client/components/Dashboard/DashSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
AUTHENTICATION_PAGE,
BILLING_PAGE,
MEMBERS_PAGE,
ORG_INTEGRATIONS_PAGE,
ORG_SETTINGS_PAGE,
TEAMS_PAGE
} from '../../utils/constants'
Expand Down Expand Up @@ -123,6 +124,11 @@ const DashSidebar = (props: Props) => {
href={`/me/organizations/${orgId}/${ORG_SETTINGS_PAGE}`}
label={'Organization Settings'}
/>
<NavItem
icon={'appRegistration'}
href={`/me/organizations/${orgId}/${ORG_INTEGRATIONS_PAGE}`}
label={'Integration Settings'}
/>
<NavItem
icon={'key'}
href={`/me/organizations/${orgId}/${AUTHENTICATION_PAGE}`}
Expand Down
2 changes: 2 additions & 0 deletions packages/client/components/Dashboard/LeftDashNavItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import styled from '@emotion/styled'
import {
AccountBox,
Add,
AppRegistration,
ArrowBack,
AutoAwesome,
CreditScore,
Expand Down Expand Up @@ -72,6 +73,7 @@ const iconLookup = {
groups: <Groups fontSize='inherit' />,
warning: <Warning fontSize='inherit' />,
work: <WorkOutline fontSize='inherit' />,
appRegistration: <AppRegistration fontSize='inherit' />,
timeline: <Timeline fontSize='inherit' />,
key: <Key fontSize='inherit' />
}
Expand Down
7 changes: 7 additions & 0 deletions packages/client/components/Dashboard/MobileDashSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
AUTHENTICATION_PAGE,
BILLING_PAGE,
MEMBERS_PAGE,
ORG_INTEGRATIONS_PAGE,
ORG_SETTINGS_PAGE,
TEAMS_PAGE
} from '../../utils/constants'
Expand Down Expand Up @@ -169,6 +170,12 @@ const MobileDashSidebar = (props: Props) => {
href={`/me/organizations/${orgId}/${ORG_SETTINGS_PAGE}`}
label={'Organization Settings'}
/>
<NavItem
onClick={handleMenuClick}
icon={'appRegistration'}
href={`/me/organizations/${orgId}/${ORG_INTEGRATIONS_PAGE}`}
label={'Integration Settings'}
/>
<NavItem
onClick={handleMenuClick}
icon={'key'}
Expand Down
3 changes: 2 additions & 1 deletion packages/client/components/Settings/SettingsWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import styled from '@emotion/styled'
import {Layout} from '../../types/constEnums'

const SettingsWrapper = styled('div')<{narrow?: boolean}>(({narrow}) => ({
display: 'flex',
flexDirection: 'column',
margin: '0 auto',
maxWidth: narrow ? 644 : 768,
maxWidth: narrow ? Layout.SETTINGS_NARROW_MAX_WIDTH : Layout.SETTINGS_MAX_WIDTH,
width: '100%'
}))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import {Done as DoneIcon, MoreVert as MoreVertIcon} from '@mui/icons-material'
import graphql from 'babel-plugin-relay/macro'
import React from 'react'
import {useFragment} from 'react-relay'
import {GitLabProviderRow_viewer$key} from '../../../../__generated__/GitLabProviderRow_viewer.graphql'
import FlatButton from '../../../../components/FlatButton'
import GitLabProviderLogo from '../../../../components/GitLabProviderLogo'
import ProviderActions from '../../../../components/ProviderActions'
import RowInfo from '../../../../components/Row/RowInfo'
import RowInfoCopy from '../../../../components/Row/RowInfoCopy'
import useAtmosphere from '../../../../hooks/useAtmosphere'
import useBreakpoint from '../../../../hooks/useBreakpoint'
import {MenuPosition} from '../../../../hooks/useCoords'
import useMenu from '../../../../hooks/useMenu'
import useMutationProps from '../../../../hooks/useMutationProps'
import {Breakpoint} from '../../../../types/constEnums'
import GitLabClientManager from '../../../../utils/GitLabClientManager'
import ConnectButton from './ConnectButton'
import GitLabConfigMenu from './GitLabConfigMenu'
import ProviderRow from './ProviderRow'

interface Props {
teamId: string
Expand All @@ -22,6 +29,7 @@ graphql`
gitlab {
auth {
provider {
id
scope
}
}
Expand All @@ -30,6 +38,11 @@ graphql`
clientId
serverBaseUrl
}
sharedProviders {
id
clientId
serverBaseUrl
}
}
}
}
Expand All @@ -56,6 +69,7 @@ const GitLabProviderRow = (props: Props) => {
menuProps,
togglePortal
} = useMenu(MenuPosition.UPPER_RIGHT)
const isDesktop = useBreakpoint(Breakpoint.SIDEBAR_LEFT)

const viewer = useFragment(
graphql`
Expand All @@ -70,22 +84,78 @@ const GitLabProviderRow = (props: Props) => {
const {teamMember} = viewer
const {integrations} = teamMember!
const {gitlab} = integrations
const {auth, cloudProvider} = gitlab
if (!cloudProvider) return null
const {clientId, id: cloudProviderId, serverBaseUrl} = cloudProvider
const {auth, cloudProvider, sharedProviders} = gitlab
const connected = !!auth
const connectedProviderId = auth?.provider?.id
const availableProviders = [...(cloudProvider ? [cloudProvider] : []), ...sharedProviders]

if (availableProviders.length === 0) return null

return (
<>
<ProviderRow
connected={!!auth}
onConnectClick={() => openOAuth(cloudProviderId, clientId, serverBaseUrl)}
submitting={submitting}
togglePortal={togglePortal}
menuRef={menuRef}
providerName={'GitLab'}
providerDescription={'Use GitLab Issues from within Parabol'}
providerLogo={<GitLabProviderLogo />}
/>
<div className='relative my-4 flex w-full shrink-0 flex-col justify-start rounded bg-white shadow-card'>
<div className='flex justify-start p-row-gutter pb-0'>
<GitLabProviderLogo />
<div className='flex w-full flex-col'>
{availableProviders.map(({id, serverBaseUrl, clientId}) => {
const showProvider = !connected || id === connectedProviderId
const isCloudProvider = cloudProvider?.id === id
if (!showProvider) return null
return (
<div key={id} className='flex w-full flex-row pb-4'>
<RowInfo>
<div className='mr-4 flex items-center align-middle font-semibold leading-6 text-slate-700'>
{isCloudProvider ? 'GitLab' : serverBaseUrl.replace(/https:\/\//, '')}
</div>
<RowInfoCopy>
{isCloudProvider
? 'Use GitLab Issues from within Parabol.'
: 'Connect to your own GitLab server.'}
</RowInfoCopy>
</RowInfo>
<ProviderActions>
{!connected && (
<ConnectButton
onConnectClick={() => openOAuth(id, clientId, serverBaseUrl)}
submitting={submitting}
/>
)}
{id === connectedProviderId && (
<>
{isDesktop ? (
<>
<div className='flex items-center pr-6'>
<DoneIcon className='h-[18px] w-[18px] text-lg text-success-light' />
<div className='pl-[6px] text-sm font-semibold text-slate-700'>
Connected
</div>
</div>
<FlatButton
className='min-w-[30px] border-slate-400 pl-0 pr-0 text-sm font-semibold text-slate-700'
onClick={togglePortal}
ref={menuRef}
>
<MoreVertIcon className='h-[18px] w-[18px] text-lg' />
</FlatButton>
</>
) : (
<FlatButton
className='min-w-[36px] border-slate-400 pl-0 pr-0 text-sm font-semibold text-slate-700'
onClick={togglePortal}
ref={menuRef}
>
<MoreVertIcon />
</FlatButton>
)}
</>
)}
</ProviderActions>
</div>
)
})}
</div>
</div>
</div>
{menuPortal(
<GitLabConfigMenu menuProps={menuProps} mutationProps={mutationProps} teamId={teamId} />
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from '@emotion/styled'
import graphql from 'babel-plugin-relay/macro'
import React, {FormEvent} from 'react'
import React, {FormEvent, useEffect} from 'react'
import {useFragment} from 'react-relay'
import {MSTeamsPanel_viewer$key} from '~/__generated__/MSTeamsPanel_viewer.graphql'
import {MenuPosition} from '~/hooks/useCoords'
Expand Down Expand Up @@ -105,6 +105,12 @@ const MSTeamsPanel = (props: Props) => {
}
}
})
// because we render this panel also when isConnectClicked, we cannot guarantee the serverWebhookUrl is correct on first render
useEffect(() => {
if (serverWebhookUrl && !fields.webhookUrl.value) {
fields.webhookUrl.resetValue(serverWebhookUrl)
}
}, [serverWebhookUrl])

const {
submitting,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ interface Props {
}

graphql`
fragment MSTeamsProviderRowTeamMember on TeamMember {
integrations {
msTeams {
auth {
provider {
id
}
fragment MSTeamsProviderRowTeamMemberIntegrations on TeamMemberIntegrations {
msTeams {
auth {
provider {
id
}
}
}
Expand All @@ -37,7 +35,9 @@ const MSTeamsProviderRow = (props: Props) => {
fragment MSTeamsProviderRow_viewer on User {
...MSTeamsPanel_viewer
teamMember(teamId: $teamId) {
...MSTeamsProviderRowTeamMember @relay(mask: false)
integrations {
...MSTeamsProviderRowTeamMemberIntegrations @relay(mask: false)
}
}
}
`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from '@emotion/styled'
import {Info as InfoIcon} from '@mui/icons-material'
import graphql from 'babel-plugin-relay/macro'
import React, {FormEvent} from 'react'
import React, {FormEvent, useEffect} from 'react'
import {useFragment} from 'react-relay'
import {MattermostPanel_viewer$key} from '~/__generated__/MattermostPanel_viewer.graphql'
import {MenuPosition} from '~/hooks/useCoords'
Expand Down Expand Up @@ -119,6 +119,12 @@ const MattermostPanel = (props: Props) => {
}
}
})
// because we render this panel also when isConnectClicked, we cannot guarantee the serverWebhookUrl is correct on first render
useEffect(() => {
if (serverWebhookUrl && !fields.webhookUrl.value) {
fields.webhookUrl.resetValue(serverWebhookUrl)
}
}, [serverWebhookUrl])

const {
submitting,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ interface Props {
}

graphql`
fragment MattermostProviderRowTeamMember on TeamMember {
integrations {
mattermost {
auth {
provider {
id
}
fragment MattermostProviderRowTeamMemberIntegrations on TeamMemberIntegrations {
mattermost {
auth {
provider {
id
}
}
}
Expand All @@ -37,7 +35,9 @@ const MattermostProviderRow = (props: Props) => {
fragment MattermostProviderRow_viewer on User {
...MattermostPanel_viewer
teamMember(teamId: $teamId) {
...MattermostProviderRowTeamMember @relay(mask: false)
integrations {
...MattermostProviderRowTeamMemberIntegrations @relay(mask: false)
}
}
}
`,
Expand Down
Loading

0 comments on commit 8806839

Please sign in to comment.