Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(orgAdmin): Add org admin teaser in org team page for non-enterprise orgs #10253

Merged
merged 13 commits into from
Oct 16, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {Button} from '../../../../ui/Button/Button'
import {useDialogState} from '../../../../ui/Dialog/useDialogState'
import plural from '../../../../utils/plural'
import OrgTeamsRow from './OrgTeamsRow'
import TeaserOrgTeamsRow from './TeaserOrgTeamsRow'

type Props = {
organizationRef: OrgTeams_organization$key
Expand All @@ -18,12 +19,16 @@ const OrgTeams = (props: Props) => {
graphql`
fragment OrgTeams_organization on Organization {
id
isOrgAdmin
tier
hasPublicTeamsFlag: featureFlag(featureName: "publicTeams")
allTeams {
id
...OrgTeamsRow_team
}
viewerTeams {
id
}
allTeamsCount
}
`,
organizationRef
Expand All @@ -35,18 +40,15 @@ const OrgTeams = (props: Props) => {
isOpen: isAddTeamDialogOpened
} = useDialogState()

const {allTeams, isOrgAdmin, hasPublicTeamsFlag} = organization
const showAllTeams = isOrgAdmin || hasPublicTeamsFlag
const {allTeams, tier, viewerTeams, allTeamsCount, hasPublicTeamsFlag} = organization
const showAllTeams = allTeams.length === allTeamsCount || hasPublicTeamsFlag
const viewerTeamCount = viewerTeams.length

return (
<div className='max-w-4xl pb-4'>
<div className='flex items-center justify-center py-1'>
<div>
<h1 className='text-2xl font-semibold leading-7'>Teams</h1>
<p className='text-gray-600 mb-2'>
{!showAllTeams
? "Only showing teams you're a member of"
: 'Showing all teams in the organization'}
</p>
</div>
<div className='ml-auto'>
<Button
Expand All @@ -60,17 +62,27 @@ const OrgTeams = (props: Props) => {
</div>
</div>

<div className='divide-y divide-slate-300 overflow-hidden rounded-md border border-slate-300 bg-white shadow-sm'>
<div className='overflow-hidden rounded-md border border-slate-300 bg-white shadow-sm'>
<div className='bg-slate-100 px-4 py-2'>
<div className='flex w-full justify-between'>
<div className='flex items-center font-bold'>
{allTeams.length} {plural(allTeams.length, 'Team')}
{allTeamsCount} {plural(allTeamsCount, 'Team')}{' '}
{!showAllTeams ? `(${allTeamsCount - viewerTeamCount} hidden)` : null}
</div>
</div>
</div>
{allTeams.map((team) => (
<OrgTeamsRow key={team.id} teamRef={team} />
))}
<div className='divide-y divide-slate-300 border-y border-slate-300'>
{allTeams.map((team) => (
<OrgTeamsRow key={team.id} teamRef={team} />
))}
</div>

{tier !== 'enterprise' && allTeamsCount > viewerTeamCount && !showAllTeams && (
<TeaserOrgTeamsRow
hiddenTeamCount={allTeamsCount - viewerTeamCount}
orgId={organization.id}
/>
)}
</div>

{isAddTeamDialogOpened ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {Lock} from '@mui/icons-material'
import React from 'react'
import {useHistory} from 'react-router'
import plural from '../../../../utils/plural'

type Props = {
hiddenTeamCount: number
orgId: string
}

const TeaserOrgTeamsRow = (props: Props) => {
const {hiddenTeamCount, orgId} = props
const history = useHistory()

const handleParabolEnterpriseClick = () => {
history.push(`/me/organizations/${orgId}/billing`)
}

return (
<div className='block cursor-default select-none'>
<div className='flex items-center p-4'>
<div className='flex flex-1 flex-col py-1'>
<div className='flex items-center text-lg font-bold'>
{hiddenTeamCount} {plural(hiddenTeamCount, 'Hidden Team')}
</div>
<div className='flex items-center justify-between'>
<div className='text-gray-600'>
<a
href='#'
onClick={handleParabolEnterpriseClick}
className='font-bold text-sky-500 hover:text-sky-600'
>
Parabol Enterprise
</a>{' '}
includes our Org Admin role, which allows you to <strong>see all teams</strong> in
your organization.
</div>
</div>
</div>
<div className='flex items-center justify-center'>
<div className='flex h-8 w-6 flex-row items-center py-2'>
<Lock className='h-6 w-6 text-slate-600' />
</div>
</div>
</div>
</div>
)
}

export default TeaserOrgTeamsRow
5 changes: 5 additions & 0 deletions packages/server/graphql/public/typeDefs/Organization.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ type Organization {
"""
allTeams: [Team!]!

"""
The count of all teams in the organization
"""
allTeamsCount: Int!

"""
all the teams the viewer is on in the organization
"""
Expand Down
5 changes: 5 additions & 0 deletions packages/server/graphql/public/types/Organization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ const Organization: OrganizationResolvers = {
}
},

allTeamsCount: async ({id: orgId}, _args, {dataLoader}) => {
const allTeamsOnOrg = await dataLoader.get('teamsByOrgIds').load(orgId)
return allTeamsOnOrg?.length ?? 0
},

viewerTeams: async ({id: orgId}, _args, {dataLoader, authToken}) => {
const allTeamsOnOrg = await dataLoader.get('teamsByOrgIds').load(orgId)
return allTeamsOnOrg
Expand Down
Loading