mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 08:37:49 +00:00
Center plain Project table cells and label the linked PR overflow (#34532)
* fix(github-project): make linked PR numbers clickable * fix: open linked pull requests at their exact URLs * test: assert complete project relation cell text * fix: clarify linked pull request controls and overflow * Fix linked pull request focus clipping and overflow label * Keep linked pull request overflow outside clipped values * fix(github-project): center plain project cells and say what +N means Drop the clickable linked PR numbers: the numbers stay plain text as before. Plain text cells (repository, parent issue, linked pull requests, sub-issue progress) now center vertically like the other cells, and the linked PR overflow reads "+N more" instead of a bare "+N". * fix(github-project): keep the linked PR "+N more" visible when numbers truncate
This commit is contained in:
@@ -83,12 +83,14 @@ export default function ProjectCell({
|
||||
}
|
||||
if (field.dataType === 'REPOSITORY') {
|
||||
return (
|
||||
<span className="truncate text-xs text-muted-foreground">{row.content.repository ?? ''}</span>
|
||||
<span className="min-w-0 self-center truncate text-xs text-muted-foreground">
|
||||
{row.content.repository ?? ''}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
if (field.dataType === 'PARENT_ISSUE') {
|
||||
return (
|
||||
<span className="truncate text-xs text-muted-foreground">
|
||||
<span className="min-w-0 self-center truncate text-xs text-muted-foreground">
|
||||
{row.content.parentIssue ? `#${row.content.parentIssue.number}` : ''}
|
||||
</span>
|
||||
)
|
||||
@@ -99,14 +101,23 @@ export default function ProjectCell({
|
||||
return <span className="text-xs text-muted-foreground" />
|
||||
}
|
||||
const labels = linked.pullRequests.map((pr) => `#${pr.number}`)
|
||||
const overflow =
|
||||
linked.totalCount > linked.pullRequests.length
|
||||
? ` +${linked.totalCount - linked.pullRequests.length}`
|
||||
: ''
|
||||
const overflow = linked.totalCount - linked.pullRequests.length
|
||||
// Only the numbers truncate, so "+N more" stays visible in narrow columns.
|
||||
return (
|
||||
<span className="truncate text-xs text-muted-foreground">
|
||||
{labels.join(', ')}
|
||||
{overflow}
|
||||
<span className="flex min-w-0 items-center gap-1 self-center text-xs text-muted-foreground">
|
||||
<span className="truncate">{labels.join(', ')}</span>
|
||||
{overflow > 0 ? (
|
||||
<>
|
||||
{' '}
|
||||
<span className="shrink-0">
|
||||
{translate(
|
||||
'auto.components.github.project.ProjectCell.linkedPullRequestsOverflow',
|
||||
'+{{count}} more',
|
||||
{ count: overflow }
|
||||
)}
|
||||
</span>
|
||||
</>
|
||||
) : null}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
@@ -116,7 +127,7 @@ export default function ProjectCell({
|
||||
return <span className="text-xs text-muted-foreground" />
|
||||
}
|
||||
return (
|
||||
<span className="truncate text-xs text-muted-foreground">
|
||||
<span className="min-w-0 self-center truncate text-xs text-muted-foreground">
|
||||
{progress.completed}/{progress.total} ({progress.percentCompleted}%)
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -3364,7 +3364,8 @@
|
||||
"9cb1a0c984": "Add text",
|
||||
"2e26a06c70": "Add label",
|
||||
"36341ffc66": "Assign",
|
||||
"e369bf4fec": "Select"
|
||||
"e369bf4fec": "Select",
|
||||
"linkedPullRequestsOverflow": "+{{count}} more"
|
||||
},
|
||||
"ProjectGroupHeader": {
|
||||
"82a22d2079": "Current",
|
||||
|
||||
@@ -128,17 +128,17 @@ describe('project field writes', () => {
|
||||
.getState()
|
||||
.updateProjectFieldValue(key, 'row', 'status', { kind: 'single-select', optionId: 'done' })
|
||||
expect(field(store)).toMatchObject({ optionId: 'done', name: 'Done', color: 'PURPLE' })
|
||||
expect(visibleRelations()).toEqual(['#12 +2', '1/2 (50%)'])
|
||||
expect(visibleRelations()).toEqual(['#12 +2 more', '1/2 (50%)'])
|
||||
const clear = store.getState().clearProjectFieldValue(key, 'row', 'status')
|
||||
expect(field(store)).toBeUndefined()
|
||||
expect(visibleRelations()).toEqual(['#12 +2', '1/2 (50%)'])
|
||||
expect(visibleRelations()).toEqual(['#12 +2 more', '1/2 (50%)'])
|
||||
await vi.waitFor(() => expect(mockApi.gh.updateProjectItemField).toHaveBeenCalledTimes(1))
|
||||
expect(mockApi.gh.clearProjectItemField).not.toHaveBeenCalled()
|
||||
first.resolve({ ok: true })
|
||||
await Promise.all([update, clear])
|
||||
expect(mockApi.gh.clearProjectItemField).toHaveBeenCalledTimes(1)
|
||||
expect(field(store)).toBeUndefined()
|
||||
expect(visibleRelations()).toEqual(['#12 +2', '1/2 (50%)'])
|
||||
expect(visibleRelations()).toEqual(['#12 +2 more', '1/2 (50%)'])
|
||||
})
|
||||
|
||||
it.each([true, false])(
|
||||
|
||||
@@ -101,7 +101,7 @@ describe('createGitHubSlice.fetchProjectViewTable coordination', () => {
|
||||
expect(groups.map((group) => group.label)).toEqual(['1', '2'])
|
||||
expect(groups.flatMap((group) => group.rows.map(projectRelationCellText))).toEqual([
|
||||
['', ''],
|
||||
['#12 +2', '1/2 (50%)']
|
||||
['#12 +2 more', '1/2 (50%)']
|
||||
])
|
||||
expect(cached.rows[1].content).not.toHaveProperty('linkedPullRequests')
|
||||
expect(cached.rows[1].content).not.toHaveProperty('subIssuesProgress')
|
||||
|
||||
@@ -70,7 +70,11 @@ const args = {
|
||||
unsupportedFields: new Set<OptionalProjectItemField>(),
|
||||
host: 'acme.ghe.com'
|
||||
} as const
|
||||
const prText = '#1, #2, #3, #4, #5, #6, #7, #8, #9, #10 +2'
|
||||
const prText = '#1, #2, #3, #4, #5, #6, #7, #8, #9, #10 +2 more'
|
||||
// The linked PR overflow renders in its own span, so match the element holding the whole cell text.
|
||||
const cellText = (text: string) => (_: string, element: Element | null) =>
|
||||
element?.textContent === text &&
|
||||
!Array.from(element.children).some((child) => child.textContent === text)
|
||||
const missingSummary = {
|
||||
extensions: { code: 'undefinedField', typeName: 'Issue', fieldName: 'subIssuesSummary' },
|
||||
message: "Field 'subIssuesSummary' doesn't exist on type 'Issue'"
|
||||
@@ -188,7 +192,7 @@ describe('Project columns from the items response', () => {
|
||||
}
|
||||
const row = normalized(page.page.nodes[0])
|
||||
renderColumns(row)
|
||||
expect(screen.getByText(expectedText).textContent).toBe(expectedText)
|
||||
expect(screen.getByText(cellText(expectedText)).textContent).toBe(expectedText)
|
||||
expect(row.fieldValuesByFieldId).toEqual({
|
||||
notes: { kind: 'text', fieldId: 'notes', text: 'Keep this too' }
|
||||
})
|
||||
@@ -253,7 +257,7 @@ describe('Project columns from the items response', () => {
|
||||
expect(warning).toHaveBeenCalledTimes(parentDropped ? 1 : 0)
|
||||
renderColumns(result.rows[0])
|
||||
expect(Boolean(screen.queryByText('1/2 (50%)'))).toBe(summary)
|
||||
expect(Boolean(screen.queryByText(prText))).toBe(prs)
|
||||
expect(Boolean(screen.queryByText(cellText(prText)))).toBe(prs)
|
||||
expect(ghExecFileAsync).toHaveBeenCalledTimes(2)
|
||||
const query = vi.mocked(ghExecFileAsync).mock.calls[1][0].join(' ')
|
||||
expect(query.includes('parent {')).toBe(!parentDropped)
|
||||
@@ -397,7 +401,8 @@ describe('Project columns from the items response', () => {
|
||||
row.content.linkedPullRequests.totalCount = totalCount
|
||||
renderColumns(row)
|
||||
expect(
|
||||
screen.getByText(totalCount === 12 ? prText : prText.replace(' +2', '')).textContent
|
||||
screen.getByText(cellText(totalCount === 12 ? prText : prText.replace(' +2 more', '')))
|
||||
.textContent
|
||||
).toBeTruthy()
|
||||
})
|
||||
|
||||
@@ -453,7 +458,7 @@ describe('Project columns from the items response', () => {
|
||||
const groups = groupRows(table, sorted)
|
||||
expect(groups.map((group) => group.label)).toEqual(['1', '2'])
|
||||
renderColumns(groups[1].rows[0])
|
||||
expect(screen.getByText(prText)).toBeTruthy()
|
||||
expect(screen.getByText(cellText(prText))).toBeTruthy()
|
||||
expect(screen.getByText('1/2 (50%)')).toBeTruthy()
|
||||
cleanup()
|
||||
renderColumns(groups[0].rows[0])
|
||||
@@ -519,7 +524,7 @@ describe('Project columns from the items response', () => {
|
||||
expect(arguments_.join(' ')).toContain('pullRequests(first:10)')
|
||||
}
|
||||
renderColumns(result.rows[count - 1])
|
||||
expect(screen.getByText(prText)).toBeTruthy()
|
||||
expect(screen.getByText(cellText(prText))).toBeTruthy()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user