diff --git a/src/renderer/src/components/github-project/ProjectCell.tsx b/src/renderer/src/components/github-project/ProjectCell.tsx index e7e3f59589a..ade697abcf6 100644 --- a/src/renderer/src/components/github-project/ProjectCell.tsx +++ b/src/renderer/src/components/github-project/ProjectCell.tsx @@ -83,12 +83,14 @@ export default function ProjectCell({ } if (field.dataType === 'REPOSITORY') { return ( - {row.content.repository ?? ''} + + {row.content.repository ?? ''} + ) } if (field.dataType === 'PARENT_ISSUE') { return ( - + {row.content.parentIssue ? `#${row.content.parentIssue.number}` : ''} ) @@ -99,14 +101,23 @@ export default function ProjectCell({ return } 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 ( - - {labels.join(', ')} - {overflow} + + {labels.join(', ')} + {overflow > 0 ? ( + <> + {' '} + + {translate( + 'auto.components.github.project.ProjectCell.linkedPullRequestsOverflow', + '+{{count}} more', + { count: overflow } + )} + + + ) : null} ) } @@ -116,7 +127,7 @@ export default function ProjectCell({ return } return ( - + {progress.completed}/{progress.total} ({progress.percentCompleted}%) ) diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index d0032297851..2b12409b1bb 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -3364,7 +3364,8 @@ "9cb1a0c984": "Add text", "2e26a06c70": "Add label", "36341ffc66": "Assign", - "e369bf4fec": "Select" + "e369bf4fec": "Select", + "linkedPullRequestsOverflow": "+{{count}} more" }, "ProjectGroupHeader": { "82a22d2079": "Current", diff --git a/src/renderer/src/store/github/project-field-mutations.test.ts b/src/renderer/src/store/github/project-field-mutations.test.ts index 5fcbb47b59f..0fedd98b403 100644 --- a/src/renderer/src/store/github/project-field-mutations.test.ts +++ b/src/renderer/src/store/github/project-field-mutations.test.ts @@ -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])( diff --git a/src/renderer/src/store/slices/github-project-request-coordination.test.ts b/src/renderer/src/store/slices/github-project-request-coordination.test.ts index 72cb784d6f4..5423e251553 100644 --- a/src/renderer/src/store/slices/github-project-request-coordination.test.ts +++ b/src/renderer/src/store/slices/github-project-request-coordination.test.ts @@ -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') diff --git a/tests/e2e/github-project-provider-columns.unit.test.ts b/tests/e2e/github-project-provider-columns.unit.test.ts index 0d382fdd9c6..76bc2eb0cfe 100644 --- a/tests/e2e/github-project-provider-columns.unit.test.ts +++ b/tests/e2e/github-project-provider-columns.unit.test.ts @@ -70,7 +70,11 @@ const args = { unsupportedFields: new Set(), 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() } ) })