Skip to content

Commit 512cf5f

Browse files
authored
Redesigned report header (#381)
1 parent 9b3f277 commit 512cf5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+700
-440
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1313

1414
### Changed
1515
- Inherit font-size instead of setting at 14px ([#377](https://github.com/cucumber/react-components/pull/377))
16+
- Redesigned report header block ([#381](https://github.com/cucumber/react-components/pull/381))
1617
- BREAKING CHANGE: Remove props from `<StatusesSummary/>`, `<ExecutionSummary/>` and `<SearchBar/>` components, use contexts for state ([#374](https://github.com/cucumber/react-components/pull/374))
1718

1819
### Removed

package-lock.json

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ciCommitLink.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ describe('ciCommitLink(ci)', () => {
4040
name: 'SuperCI',
4141
}
4242

43-
expect(ciCommitLink(ci)).to.eq(null)
43+
expect(ciCommitLink(ci)).to.eq(undefined)
4444
})
4545
})
4646
})

src/ciCommitLink.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import * as messages from '@cucumber/messages'
1+
import { Ci } from '@cucumber/messages'
22

33
import toRepositoryId from './toRepositoryId.js'
44

5-
export default function ciCommitLink(ci: messages.Ci): string | null {
5+
// TODO move upstream to create-meta
6+
export default function ciCommitLink(ci: Ci): string | undefined {
67
if (ci.git && ci.git.remote) {
78
const repositoryId = toRepositoryId(ci.git.remote)
89
const github = repositoryId.startsWith('github.com') || ci.name === 'GitHub Actions'
910
if (ci.git.revision && github) {
1011
return `https://${repositoryId}/commit/${ci.git.revision}`
1112
}
1213
}
13-
return null
1414
}

src/components/app/CICommitLink.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
1-
import * as messages from '@cucumber/messages'
2-
import { faLink } from '@fortawesome/free-solid-svg-icons'
1+
import { Ci } from '@cucumber/messages'
2+
import { faCodeCommit } from '@fortawesome/free-solid-svg-icons'
33
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4-
import React from 'react'
4+
import React, { FC } from 'react'
55

66
import ciCommitLink from '../../ciCommitLink.js'
77

8-
interface IProps {
9-
ci: messages.Ci
10-
}
8+
export const CICommitLink: FC<{
9+
ci: Ci
10+
}> = ({ ci }) => {
11+
if (!ci.git) {
12+
return null
13+
}
1114

12-
export const CICommitLink: React.FunctionComponent<IProps> = ({ ci: ci }) => {
15+
const shortHash = ci.git.revision.substring(0, 7)
1316
const commitLink = ciCommitLink(ci)
1417

15-
if (commitLink && ci.git?.remote) {
18+
if (commitLink) {
1619
return (
1720
<>
18-
<FontAwesomeIcon icon={faLink} />
19-
Git Ref <a href={commitLink}>{ci.git.revision.substring(0, 7)}</a>
21+
<FontAwesomeIcon aria-hidden="true" style={{ opacity: 0.75 }} icon={faCodeCommit} />
22+
<a href={commitLink} target="_blank" rel="noreferrer">
23+
<code>{shortHash}</code>
24+
</a>
2025
</>
2126
)
2227
}
2328
return (
2429
<>
25-
<FontAwesomeIcon icon={faLink} /> Git Ref {ci.git?.revision.substring(0, 7)}
30+
<FontAwesomeIcon aria-hidden="true" style={{ opacity: 0.75 }} icon={faCodeCommit} />
31+
<code>{shortHash}</code>
2632
</>
2733
)
2834
}

src/components/app/CIJobLink.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
import * as messages from '@cucumber/messages'
2-
import { faLink } from '@fortawesome/free-solid-svg-icons'
1+
import { Ci } from '@cucumber/messages'
2+
import { faServer } from '@fortawesome/free-solid-svg-icons'
33
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4-
import React from 'react'
4+
import React, { FC } from 'react'
55

6-
interface IProps {
7-
ci: messages.Ci
8-
}
9-
10-
export const CIJobLink: React.FunctionComponent<IProps> = ({ ci: ci }) => {
11-
if (ci.url && ci.buildNumber) {
6+
export const CIJobLink: FC<{
7+
ci: Ci
8+
}> = ({ ci }) => {
9+
if (ci.url) {
1210
return (
1311
<>
14-
<FontAwesomeIcon icon={faLink} />
15-
Job <a href={ci.url}> {ci.buildNumber}</a>
12+
<FontAwesomeIcon aria-hidden="true" style={{ opacity: 0.75 }} icon={faServer} />
13+
<a href={ci.url} target="_blank" rel="noreferrer">
14+
{ci.name}
15+
</a>
1616
</>
1717
)
1818
}
19-
return <></>
19+
return (
20+
<>
21+
<FontAwesomeIcon aria-hidden="true" style={{ opacity: 0.75 }} icon={faServer} />
22+
<span>{ci.name}</span>
23+
</>
24+
)
2025
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@import '../../styles/theming';
2+
3+
.button {
4+
background-color: transparent;
5+
font-size: inherit;
6+
padding: 0;
7+
border: none;
8+
color: $anchorColor;
9+
cursor: pointer;
10+
11+
&:disabled {
12+
cursor: unset;
13+
}
14+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { render, screen, waitFor } from '@testing-library/react'
2+
import { userEvent } from '@testing-library/user-event'
3+
import { expect } from 'chai'
4+
import React from 'react'
5+
import sinon from 'sinon'
6+
7+
import { CopyButton } from './CopyButton.js'
8+
9+
describe('<CopyButton/>', () => {
10+
const originalClipboard = navigator.clipboard
11+
12+
before(() => {
13+
// @ts-expect-error overriding navigator.clipboard
14+
navigator.clipboard = {
15+
writeText: sinon.stub().resolves(),
16+
}
17+
})
18+
19+
after(() => {
20+
// @ts-expect-error overriding navigator.clipboard
21+
navigator.clipboard = originalClipboard
22+
})
23+
24+
it('should copy text to clipboard, then disable and show checkmark', async () => {
25+
render(<CopyButton text="test text" />)
26+
27+
await userEvent.click(screen.getByRole('button', { name: 'Copy' }))
28+
29+
await waitFor(() => {
30+
expect(screen.getByRole('button', { name: 'Copied' })).to.be.visible
31+
expect(screen.getByRole('button', { name: 'Copied' })).to.have.property('disabled', true)
32+
expect(navigator.clipboard.writeText).to.have.been.calledOnceWithExactly('test text')
33+
})
34+
})
35+
})

src/components/app/CopyButton.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons'
2+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3+
import React, { FC, useState } from 'react'
4+
5+
import styles from './CopyButton.module.scss'
6+
7+
export const CopyButton: FC<{ text: string }> = ({ text }) => {
8+
const [copied, setCopied] = useState(false)
9+
10+
const handleCopy = () => {
11+
navigator.clipboard
12+
.writeText(text)
13+
.then(() => {
14+
setCopied(true)
15+
setTimeout(() => {
16+
setCopied(false)
17+
}, 3000)
18+
})
19+
.catch((err) => {
20+
console.error('Failed to copy', err)
21+
})
22+
}
23+
24+
return (
25+
<button
26+
onClick={handleCopy}
27+
aria-label={copied ? 'Copied' : 'Copy'}
28+
disabled={copied}
29+
className={styles.button}
30+
>
31+
<FontAwesomeIcon icon={copied ? faCheck : faCopy} />
32+
</button>
33+
)
34+
}
Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,5 @@
11
@import '../../styles/theming';
22

3-
.backdrop {
4-
background-color: $panelAccentColor;
5-
border: 1px solid transparent;
6-
}
7-
8-
.list {
9-
display: grid;
10-
grid-template-columns: repeat(12, 1fr);
11-
grid-template-rows: 1fr 1fr;
12-
gap: 1px;
13-
margin: 0;
14-
text-align: center;
15-
}
16-
17-
.item {
18-
grid-column-end: span 4;
19-
display: flex;
20-
flex-direction: column-reverse;
21-
justify-content: center;
22-
padding: 1.5em;
23-
background-color: $backgroundColor;
24-
color: $textColor;
25-
26-
&Ci,
27-
&Ci ~ & {
28-
grid-column-end: span 3;
29-
}
30-
}
31-
32-
.value {
33-
font-weight: bold;
34-
font-size: 1.25em;
35-
margin: 0;
36-
37-
svg {
38-
display: inline-block;
39-
max-width: 2em;
40-
}
41-
}
42-
43-
.suffix {
44-
font-size: 1em;
45-
margin-top: 0.25em;
3+
.conjunction {
464
color: $codeTextColor;
475
}
48-
49-
.gitItem {
50-
display: inline-flex;
51-
gap: 0.25em;
52-
53-
& + & {
54-
margin-left: 1em;
55-
}
56-
57-
a {
58-
color: $anchorColor;
59-
}
60-
}

0 commit comments

Comments
 (0)