Skip to content

Commit

Permalink
feat(sprint-poker): New Poker Scope UI (#6344)
Browse files Browse the repository at this point in the history
* render list of gitlab issues

* use usePaginationFragment

* increase default value for usePaginationFragment

* implement GitLabScopingSearchResultItem

* add GitLabScopingSelectAllIssues

* can add and remove gitlab issues in scope phase

* add UpdatePokerScopeMutation gitlab optimistic updater

* able to select all issues

* clean up type errors

* add projects name alias to rootSchema

* include projectIds in search query

* return iid from GitLabIssueId

* sort projects by lastActivityAt

* implement fetchGitLabProjects

* implement gitlab issue menu

* implement NewGitLabIssueMenuRoot instead of using useAllIntegrations

* load next if projects dont have any issues

* update comment

* remove gitlab menu root and use defaultProjects query to populate menu

* increase projectsFirst from 10 to 20

* query all gitlab projects

* chore(comment): how to extend BaseTaskIntegration

* able to create a new gitlab issue

* use GitLabServerManager and implement parseWebPath

* fix undefined baseUri

* changed taskIntegrationGitLab and GitLabId to use providerId

* lowercase gitlabRequest to be consistent with gh

* add handle create gitlab issue

* add info fragment and return data instead of data.issue

* add serverBaseUrl

* adjusted root schema and can now render projects in input menu again

* clean up update poker scope and create task gitlab

* fix ts errors

* add gitlab query types

* add fullPath to gitLab issue edge if exists

* get nodes appearing on insert

* get gitlab issue title in create task updater

* include webUrl in createTask query so user can click on newly create issue url

* add first and sort to allProjects query

* rename GitLabRepo to GitLabProject

* pass meetingId to issue input rather than querying it

* add gitlab search query

* filter by gitlab search query

* refactor to hooks

* query projects from project filter menu

* remove __typename and resolveTypes

* update UpdatePokerScopeMutation to fix selectAll bug

* render projects in filter menu

* use fullPath in gitlab menu and adjust max width

* refactor gitlab search query from string to object with projectIds

* selecting a project in the filter menu adds the item to selectedProjectsFullPath

* selecting a project filters the results

* add search icon

* add search icon

* remove searchQuery from scoping results query

* clean-up return statement in fetchGitLabProjects

* remove alias

* make selectedProjectIds nullable

* add search to issue args

* include search string when adding new gitlab issue

* refactor search query to a gql object

* remove useLoadNextOnScrollBottom and increase default projects first

* merge with master

* fix selectedProjects type err

* add search string to differentiate project menu query and include ids in project connection so we can add issues with a filter

* use react-swipeable-views workaround

* add _xGitLabProject resolver

* merge with master

* remove resolverTypes and gitlabTypes

* map over tabs instead of contents

* implement new scope search ui in gitlab

* refactor gitlabSearchQuery from selectedProjectsIds to selectedProjects

* selected projects showing up in current filters

* truncate current filters

* add new scope search to jira

* show jira project names

* improve current filters positioning

* remove gitlab types

* implement new scope search ui in parabol integration

* implement new scope search bar ui in github

* change filter var to status

* query projects from GitLabIntegration and remove fullPath from gitlab search query

* refactor scoping results query to usePagination and add alias to new issue query so it is not affected by parent query filtering

* fix(gitlab): add proper client-side alias handling (#6361)

* resolve to aliased fields

* resolve to aliased fields

* make poker input menu a dropdown and fix width

* refactor baseTabs to include Component

* create a single source of truth for gitlab issue args

* add viewerMeetingMember check and remove selectedProjectsIds resolver

* remove refetchable from gitlab scoping results query

* make selectedProjectsIds null if empty array

* use optional chaining rather than destructuring many vars

* feat(sprint-poker): GitLab issue is visible in Estimate phase (#6355)

* refactor PokerEstimateHeaderCard to make PokerEstimateHeaderCardContent reusable

* adding commit to play by the gh title rules

* use nullish coalescing instead of logical or

* spread headerFields into PokerEstimateHeaderCardContent

* use join method in currentFilters

Co-authored-by: Matt Krick <[email protected]>
  • Loading branch information
2 people authored and JimmyLv committed Apr 19, 2022
1 parent 6392e49 commit 1603579
Show file tree
Hide file tree
Showing 25 changed files with 541 additions and 279 deletions.
20 changes: 16 additions & 4 deletions packages/client/components/GitHubScopingSearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@ import styled from '@emotion/styled'
import graphql from 'babel-plugin-relay/macro'
import React from 'react'
import {useFragment} from 'react-relay'
import {PALETTE} from '~/styles/paletteV3'
import {GitHubScopingSearchBar_meeting$key} from '../__generated__/GitHubScopingSearchBar_meeting.graphql'
import GitHubScopingSearchFilterToggle from './GitHubScopingSearchFilterToggle'
import GitHubScopingSearchHistoryToggle from './GitHubScopingSearchHistoryToggle'
import GitHubScopingSearchInput from './GitHubScopingSearchInput'

const SearchBar = styled('div')({
padding: 16
})

const SearchBarWrapper = styled('div')({
alignItems: 'center',
border: `1px solid ${PALETTE.SLATE_400}`,
borderRadius: '40px',
display: 'flex',
padding: 16
height: 44,
padding: '0 16px',
width: '100%'
})

interface Props {
meetingRef: GitHubScopingSearchBar_meeting$key
}
Expand All @@ -32,9 +42,11 @@ const GitHubScopingSearchBar = (props: Props) => {

return (
<SearchBar>
<GitHubScopingSearchHistoryToggle meetingRef={meeting} />
<GitHubScopingSearchInput meetingRef={meeting} />
<GitHubScopingSearchFilterToggle meetingRef={meeting} />
<SearchBarWrapper>
<GitHubScopingSearchHistoryToggle meetingRef={meeting} />
<GitHubScopingSearchInput meetingRef={meeting} />
<GitHubScopingSearchFilterToggle meetingRef={meeting} />
</SearchBarWrapper>
</SearchBar>
)
}
Expand Down
30 changes: 21 additions & 9 deletions packages/client/components/GitHubScopingSearchFilterToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,30 @@ import {PALETTE} from '../styles/paletteV3'
import {ICON_SIZE} from '../styles/typographyV2'
import lazyPreload from '../utils/lazyPreload'
import {GitHubScopingSearchFilterToggle_meeting$key} from '../__generated__/GitHubScopingSearchFilterToggle_meeting.graphql'
import FlatButton from './FlatButton'
import Icon from './Icon'
import PlainButton from './PlainButton/PlainButton'

const StyledButton = styled(FlatButton)({
height: 24,
marginLeft: 4,
padding: 0,
width: 24,
background: PALETTE.SKY_500,
'&:hover': {
background: PALETTE.SKY_500
}
})

const FilterIcon = styled(Icon)({
color: PALETTE.SLATE_600,
fontSize: ICON_SIZE.MD24
color: PALETTE.WHITE,
fontSize: ICON_SIZE.MD18
})

const GitHubScopingSearchFilterMenuRoot = lazyPreload(() =>
import(
/* webpackChunkName: 'GitHubScopingSearchFilterMenuRoot' */ './GitHubScopingSearchFilterMenuRoot'
)
const GitHubScopingSearchFilterMenuRoot = lazyPreload(
() =>
import(
/* webpackChunkName: 'GitHubScopingSearchFilterMenuRoot' */ './GitHubScopingSearchFilterMenuRoot'
)
)
interface Props {
meetingRef: GitHubScopingSearchFilterToggle_meeting$key
Expand All @@ -44,9 +56,9 @@ const GitHubScopingSearchFilterToggle = (props: Props) => {
})
return (
<>
<PlainButton onClick={togglePortal} ref={originRef}>
<StyledButton onClick={togglePortal} ref={originRef}>
<FilterIcon>filter_list</FilterIcon>
</PlainButton>
</StyledButton>
{menuPortal(
<GitHubScopingSearchFilterMenuRoot
teamId={teamId}
Expand Down
2 changes: 2 additions & 0 deletions packages/client/components/GitHubScopingSearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import Icon from './Icon'
const SearchInput = styled('input')({
appearance: 'none',
border: 'none',
borderLeft: `1px solid ${PALETTE.SLATE_400}`,
color: PALETTE.SLATE_700,
fontSize: 16,
margin: 0,
padding: 12,
outline: 0,
backgroundColor: 'transparent',
width: '100%'
Expand Down
25 changes: 20 additions & 5 deletions packages/client/components/GitLabScopingSearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,32 @@ import {useFragment} from 'react-relay'
import {PALETTE} from '~/styles/paletteV3'
import {ICON_SIZE} from '~/styles/typographyV2'
import {GitLabScopingSearchBar_meeting$key} from '../__generated__/GitLabScopingSearchBar_meeting.graphql'
import GitLabScopingSearchInput from './GitLabScopingSearchInput'
import GitLabScopingSearchCurrentFilters from './GitLabScopingSearchCurrentFilters'
import GitLabScopingSearchFilterToggle from './GitLabScopingSearchFilterToggle'
import GitLabScopingSearchInput from './GitLabScopingSearchInput'
import Icon from './Icon'

const SearchIcon = styled(Icon)({
color: PALETTE.SLATE_600,
fontSize: ICON_SIZE.MD24,
padding: 3,
marginRight: 12
})

const SearchBar = styled('div')({
padding: 16
})

const SearchBarWrapper = styled('div')({
alignItems: 'center',
border: `1px solid ${PALETTE.SLATE_400}`,
borderRadius: '40px',
display: 'flex',
padding: 16
height: 44,
padding: '0 16px',
width: '100%'
})

interface Props {
meetingRef: GitLabScopingSearchBar_meeting$key
}
Expand All @@ -32,16 +43,20 @@ const GitLabScopingSearchBar = (props: Props) => {
fragment GitLabScopingSearchBar_meeting on PokerMeeting {
...GitLabScopingSearchInput_meeting
...GitLabScopingSearchFilterToggle_meeting
...GitLabScopingSearchCurrentFilters_meeting
}
`,
meetingRef
)

return (
<SearchBar>
<SearchIcon>search</SearchIcon>
<GitLabScopingSearchInput meetingRef={meeting} />
<GitLabScopingSearchFilterToggle meetingRef={meeting} />
<SearchBarWrapper>
<SearchIcon>search</SearchIcon>
<GitLabScopingSearchInput meetingRef={meeting} />
<GitLabScopingSearchFilterToggle meetingRef={meeting} />
</SearchBarWrapper>
<GitLabScopingSearchCurrentFilters meetingRef={meeting} />
</SearchBar>
)
}
Expand Down
83 changes: 83 additions & 0 deletions packages/client/components/GitLabScopingSearchCurrentFilters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import styled from '@emotion/styled'
import graphql from 'babel-plugin-relay/macro'
import React from 'react'
import {useFragment} from 'react-relay'
import {PALETTE} from '../styles/paletteV3'
import {GitLabScopingSearchCurrentFilters_meeting$key} from '../__generated__/GitLabScopingSearchCurrentFilters_meeting.graphql'

const Wrapper = styled('div')({
width: '100%',
display: 'flex',
paddingLeft: '72px',
paddingTop: '8px'
})

const Description = styled('div')({
color: PALETTE.SLATE_600,
fontSize: 16,
fontWeight: 500,
whiteSpace: 'nowrap'
})

const Items = styled('div')({
color: PALETTE.SLATE_600,
fontSize: 16,
fontWeight: 600,
fontStyle: 'italic',
padding: '0px 24px 0px 4px',
width: '100%',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis'
})

interface Props {
meetingRef: GitLabScopingSearchCurrentFilters_meeting$key
}

const GitLabScopingSearchCurrentFilters = (props: Props) => {
const {meetingRef} = props
const meeting = useFragment(
graphql`
fragment GitLabScopingSearchCurrentFilters_meeting on PokerMeeting {
gitlabSearchQuery {
selectedProjectsIds
}
viewerMeetingMember {
teamMember {
integrations {
gitlab {
projects {
... on _xGitLabProject {
id
fullPath
}
}
}
}
}
}
}
`,
meetingRef
)
const {gitlabSearchQuery, viewerMeetingMember} = meeting
const {selectedProjectsIds} = gitlabSearchQuery
const projects = viewerMeetingMember?.teamMember.integrations.gitlab.projects

const selectedProjectsPaths = [] as string[]
selectedProjectsIds?.forEach((projectId) => {
const selectedProjectPath = projects?.find((project) => project.id === projectId)?.fullPath
if (selectedProjectPath) selectedProjectsPaths.push(selectedProjectPath)
})
const currentFilters = selectedProjectsPaths.length ? selectedProjectsPaths.join(', ') : 'None'

return (
<Wrapper>
<Description>Current filters: </Description>
<Items>{currentFilters}</Items>
</Wrapper>
)
}

export default GitLabScopingSearchCurrentFilters
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const GitLabScopingSearchFilterMenu = (props: Props) => {
__typename
id
fullPath
path
}
}
}
Expand Down
30 changes: 21 additions & 9 deletions packages/client/components/GitLabScopingSearchFilterToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,30 @@ import {PALETTE} from '../styles/paletteV3'
import {ICON_SIZE} from '../styles/typographyV2'
import lazyPreload from '../utils/lazyPreload'
import {GitLabScopingSearchFilterToggle_meeting$key} from '../__generated__/GitLabScopingSearchFilterToggle_meeting.graphql'
import FlatButton from './FlatButton'
import Icon from './Icon'
import PlainButton from './PlainButton/PlainButton'

const StyledButton = styled(FlatButton)({
height: 24,
marginLeft: 4,
padding: 0,
width: 24,
background: PALETTE.SKY_500,
'&:hover': {
background: PALETTE.SKY_500
}
})

const FilterIcon = styled(Icon)({
color: PALETTE.SLATE_600,
fontSize: ICON_SIZE.MD24
color: PALETTE.WHITE,
fontSize: ICON_SIZE.MD18
})

const GitLabScopingSearchFilterMenuRoot = lazyPreload(() =>
import(
/* webpackChunkName: 'GitLabScopingSearchFilterMenuRoot' */ './GitLabScopingSearchFilterMenuRoot'
)
const GitLabScopingSearchFilterMenuRoot = lazyPreload(
() =>
import(
/* webpackChunkName: 'GitLabScopingSearchFilterMenuRoot' */ './GitLabScopingSearchFilterMenuRoot'
)
)
interface Props {
meetingRef: GitLabScopingSearchFilterToggle_meeting$key
Expand All @@ -44,9 +56,9 @@ const GitLabScopingSearchFilterToggle = (props: Props) => {
})
return (
<>
<PlainButton onClick={togglePortal} ref={originRef}>
<StyledButton onClick={togglePortal} ref={originRef}>
<FilterIcon>filter_list</FilterIcon>
</PlainButton>
</StyledButton>
{menuPortal(
<GitLabScopingSearchFilterMenuRoot
teamId={teamId}
Expand Down
2 changes: 2 additions & 0 deletions packages/client/components/GitLabScopingSearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import Icon from './Icon'
const SearchInput = styled('input')({
appearance: 'none',
border: 'none',
borderLeft: `1px solid ${PALETTE.SLATE_400}`,
color: PALETTE.SLATE_700,
fontSize: 16,
margin: 0,
padding: 12,
outline: 0,
backgroundColor: 'transparent',
width: '100%'
Expand Down
58 changes: 38 additions & 20 deletions packages/client/components/JiraScopingSearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,56 @@
import styled from '@emotion/styled'
import graphql from 'babel-plugin-relay/macro'
import {createFragmentContainer} from 'react-relay'
import {JiraScopingSearchBar_meeting} from '../__generated__/JiraScopingSearchBar_meeting.graphql'
import React from 'react'
import {useFragment} from 'react-relay'
import {PALETTE} from '~/styles/paletteV3'
import {JiraScopingSearchBar_meeting$key} from '../__generated__/JiraScopingSearchBar_meeting.graphql'
import JiraScopingSearchCurrentFilters from './JiraScopingSearchCurrentFilters'
import JiraScopingSearchFilterToggle from './JiraScopingSearchFilterToggle'
import JiraScopingSearchHistoryToggle from './JiraScopingSearchHistoryToggle'
import JiraScopingSearchInput from './JiraScopingSearchInput'
import JiraScopingSearchFilterToggle from './JiraScopingSearchFilterToggle'
import React from 'react'
import styled from '@emotion/styled'

const SearchBar = styled('div')({
padding: 16
})

const SearchBarWrapper = styled('div')({
alignItems: 'center',
border: `1px solid ${PALETTE.SLATE_400}`,
borderRadius: '40px',
display: 'flex',
padding: 16
height: 44,
padding: '0 16px',
width: '100%'
})
interface Props {
meeting: JiraScopingSearchBar_meeting
meetingRef: JiraScopingSearchBar_meeting$key
}

const JiraScopingSearchBar = (props: Props) => {
const {meeting} = props
const {meetingRef} = props

const meeting = useFragment(
graphql`
fragment JiraScopingSearchBar_meeting on PokerMeeting {
...JiraScopingSearchHistoryToggle_meeting
...JiraScopingSearchInput_meeting
...JiraScopingSearchFilterToggle_meeting
...JiraScopingSearchCurrentFilters_meeting
}
`,
meetingRef
)

return (
<SearchBar>
<JiraScopingSearchHistoryToggle meeting={meeting} />
<JiraScopingSearchInput meeting={meeting} />
<JiraScopingSearchFilterToggle meeting={meeting} />
<SearchBarWrapper>
<JiraScopingSearchHistoryToggle meeting={meeting} />
<JiraScopingSearchInput meeting={meeting} />
<JiraScopingSearchFilterToggle meeting={meeting} />
</SearchBarWrapper>
<JiraScopingSearchCurrentFilters meetingRef={meeting} />
</SearchBar>
)
}

export default createFragmentContainer(JiraScopingSearchBar, {
meeting: graphql`
fragment JiraScopingSearchBar_meeting on PokerMeeting {
...JiraScopingSearchHistoryToggle_meeting
...JiraScopingSearchInput_meeting
...JiraScopingSearchFilterToggle_meeting
}
`
})
export default JiraScopingSearchBar
Loading

0 comments on commit 1603579

Please sign in to comment.