Skip to content

Commit 8a8a225

Browse files
authored
Fix Versions page closes #410, credits to EliasVal <3 (#432)
* Fix Versions page closes #410, credits to EliasVal <3 Original author: https://github.com/EliasVal See #412 * Replace icons with text for better dark and light theme * Remove extra lines and comments * Update completed emoji for better dark and light theme * Update fontSize for arrow icon in versions list
1 parent 3711393 commit 8a8a225

14 files changed

+514
-82
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import React, { useReducer } from 'react';
2+
import CodeBlock from '@theme/CodeBlock';
3+
4+
interface Props {
5+
ciJob;
6+
ciBuild;
7+
repoVersionInfo;
8+
editorVersionInfo;
9+
style;
10+
}
11+
12+
const BuildFailureDetails = ({
13+
ciJob,
14+
repoVersionInfo,
15+
editorVersionInfo,
16+
ciBuild,
17+
...rest
18+
}: Props) => {
19+
const { editorVersion, baseOs, targetPlatform } = ciBuild.buildInfo;
20+
const { major, minor, patch } = repoVersionInfo;
21+
22+
const reducer = (state, action) => {
23+
const { tag, value } = action;
24+
return { ...state, [tag]: value };
25+
};
26+
27+
const [tags /* , dispatch */] = useReducer(reducer, {
28+
[`${baseOs}-${editorVersion}-${targetPlatform}-${major}`]: '❓',
29+
[`${baseOs}-${editorVersion}-${targetPlatform}-${major}.${minor}`]: '❓',
30+
[`${baseOs}-${editorVersion}-${targetPlatform}-${major}.${minor}.${patch}`]: '❓',
31+
[`${editorVersion}-${targetPlatform}-${major}`]: '❓',
32+
[`${editorVersion}-${targetPlatform}-${major}.${minor}`]: '❓',
33+
[`${editorVersion}-${targetPlatform}-${major}.${minor}.${patch}`]: '❓',
34+
});
35+
36+
// Todo - fetch docker info from dockerhub for all tags, or do it on the server
37+
// useEffect(() => {
38+
// (async () => {
39+
// const repo = 'unityci/editor';
40+
// for (const tag of Object.keys(tags)) {
41+
// const requestUrl = `https://index.docker.io/v1/repositories/${repo}/tags/${tag}`;
42+
// try {
43+
// const response = await fetch(requestUrl);
44+
// dispatch({ tag, value: response.status === 0 });
45+
// } catch (error) {
46+
// dispatch({ tag, value: false });
47+
// }
48+
// }
49+
// })();
50+
// }, []);
51+
52+
const { changeSet } = editorVersionInfo;
53+
const buildCommand = `#!/usr/bin/env bash
54+
git clone git@github.com:game-ci/docker.git
55+
cd docker
56+
57+
editor_version=${editorVersion}
58+
change_set=${changeSet}
59+
base_os=${baseOs}
60+
target_platform=${targetPlatform}
61+
image_name=unityci-editor:$editor_version-$target_platform
62+
63+
docker build . \\
64+
--file ./images/$base_os/editor/Dockerfile \\
65+
-t $image_name \\
66+
--build-arg=version=$editor_version \\
67+
--build-arg=changeSet=$change_set \\
68+
--build-arg=module=$target_platform
69+
`;
70+
71+
const pullCommand = `docker pull unityci/editor:${baseOs}-${editorVersion}-${targetPlatform}-${major}.${minor}.${patch}`;
72+
73+
return (
74+
<div {...rest}>
75+
<h4>CI Job identification</h4>
76+
<CodeBlock language="json">{JSON.stringify(ciJob, null, 2)}</CodeBlock>
77+
<br />
78+
<h4>Commands</h4>
79+
<p>Build the docker image locally for debugging:</p>
80+
<CodeBlock language="bash">{buildCommand}</CodeBlock>
81+
<p>Pull this docker image:</p>
82+
<CodeBlock language="bash">{pullCommand}</CodeBlock>
83+
<br />
84+
<h4>Associated tags on docker hub</h4>
85+
<CodeBlock language="json">{JSON.stringify(tags, null, 2)}</CodeBlock>
86+
<br />
87+
<h4>CI Build details</h4>
88+
<CodeBlock language="json">{JSON.stringify(ciBuild, null, 2)}</CodeBlock>
89+
</div>
90+
);
91+
};
92+
93+
export default BuildFailureDetails;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import React, { useState } from 'react';
2+
import DockerImageLinkOrRetryButton, {
3+
type Record,
4+
} from '@site/src/components/docs/versions/docker-image-link-or-retry-button';
5+
import Spinner from '@site/src/components/molecules/spinner';
6+
import Tooltip from '@site/src/components/molecules/tooltip/tooltip';
7+
import styles from './builds.module.scss';
8+
9+
const mapBuildStatusToIcon = {
10+
started: <Spinner type="slow" />,
11+
failed: '⚠',
12+
published: '✅',
13+
};
14+
15+
type Props = {
16+
children: React.JSX.Element | React.JSX.Element[];
17+
build: Record;
18+
};
19+
20+
const CopyToClipboard = (copyString: string) => {
21+
navigator.clipboard.writeText(copyString);
22+
};
23+
24+
export default function BuildRow({ children, build }: Props) {
25+
const [expanded, setExpanded] = useState(false);
26+
const [toolbarContent, setToolbarContent] = useState('Click to copy');
27+
28+
const MapBuildStatusToElement = (status: string) => {
29+
const icon = mapBuildStatusToIcon[status];
30+
31+
switch (status) {
32+
case 'started':
33+
return <Spinner type="slow" />;
34+
case 'failed':
35+
return <Tooltip content={build.failure?.reason}>{icon}</Tooltip>;
36+
case 'published':
37+
return icon;
38+
default:
39+
return status;
40+
}
41+
};
42+
43+
return (
44+
<>
45+
<tr className={styles.tableRow}>
46+
<td
47+
onClick={() => setExpanded(!expanded)}
48+
className="text-center select-none cursor-pointer text-2xl"
49+
>
50+
{expanded ? '-' : '+'}
51+
</td>
52+
<td className="text-center">{MapBuildStatusToElement(build.status)}</td>
53+
<td>
54+
<span>
55+
<Tooltip content={toolbarContent}>
56+
<button
57+
onClick={() => {
58+
CopyToClipboard(build.buildId);
59+
setToolbarContent('Copied to clipboard!');
60+
}}
61+
onMouseLeave={() => {
62+
setToolbarContent('Click to copy');
63+
}}
64+
type="button"
65+
>
66+
{build.buildId}
67+
</button>
68+
</Tooltip>
69+
<DockerImageLinkOrRetryButton record={build} />
70+
</span>
71+
</td>
72+
<td>{build.imageType}</td>
73+
<td>{build.buildInfo.baseOs}</td>
74+
<td>{build.buildInfo.targetPlatform}</td>
75+
</tr>
76+
{expanded && (
77+
<tr className={styles.expandedContentRow}>
78+
<td colSpan={6}>{children}</td>
79+
</tr>
80+
)}
81+
</>
82+
);
83+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.stickyRow:global(.ant-table-row.ant-table-row-level-0) > :global(td) {
2+
position: sticky;
3+
top: 99px; /* height of the collapse-item-header + the parent tr > td sticky */
4+
background-color: rgb(255, 255, 255);
5+
z-index: 2;
6+
box-shadow: 0 0 25px rgba(255,255,255,1), 0 0 15px rgba(255,255,255,1), 0 0 20px rgba(255,255,255,1);
7+
clip-path: inset(-25px 0 0 0);
8+
}
9+
10+
.stickyRow:global(.ant-table-row.ant-table-row-level-0) > :global(td:not(:last-child)) {
11+
clip-path: inset(-25px -1px 0 0); /* fix for space from responsive vs fixed width on cells */
12+
}
13+
14+
.expandedContentRow {
15+
height: 0;
16+
overflow: hidden;
17+
}
18+
19+
20+
.tableRow {
21+
width: 100%;
22+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react';
2+
import { useFirestore, useFirestoreCollectionData } from 'reactfire';
3+
import BuildFailureDetails from '@site/src/components/docs/versions/builds/build-failure-details';
4+
import styles from './builds.module.scss';
5+
import BuildRow from './build-row';
6+
import { Record } from '../docker-image-link-or-retry-button';
7+
8+
interface RepoVersionInfo {
9+
version: string;
10+
major: number;
11+
minor: number;
12+
patch: number;
13+
}
14+
15+
interface Props {
16+
ciJobId: string;
17+
repoVersionInfo: RepoVersionInfo;
18+
editorVersionInfo;
19+
}
20+
21+
const Builds = ({ ciJobId, repoVersionInfo, editorVersionInfo }: Props) => {
22+
const loading = <p>Fetching builds...</p>;
23+
24+
const ciBuilds = useFirestore().collection('ciBuilds').where('relatedJobId', '==', ciJobId);
25+
26+
const { status, data } = useFirestoreCollectionData<{ [key: string]: any }>(ciBuilds);
27+
const isLoading = status === 'loading';
28+
29+
if (isLoading) {
30+
return loading;
31+
}
32+
33+
const expandable = {
34+
expandedRowRender: (record) => (
35+
<BuildFailureDetails
36+
style={{ margin: 0 }}
37+
ciJob={ciJobId}
38+
editorVersionInfo={editorVersionInfo}
39+
repoVersionInfo={repoVersionInfo}
40+
ciBuild={record}
41+
/>
42+
),
43+
};
44+
45+
return (
46+
<table className="w-full max-w-screen-lg block border-collapse">
47+
<tr className={styles.tableRow}>
48+
<th> </th>
49+
<th className="text-center">Status</th>
50+
<th>Build ID</th>
51+
<th>Image type</th>
52+
<th>OS</th>
53+
<th>Target Platform</th>
54+
</tr>
55+
{data.map((build: Record) => (
56+
<BuildRow build={build}>{expandable.expandedRowRender(build)}</BuildRow>
57+
))}
58+
</table>
59+
);
60+
};
61+
62+
export default Builds;

src/components/docs/versions/date-time.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import Tooltip from '../../molecules/tooltip/tooltip';
23

34
interface Props {
45
utcSeconds: number;
@@ -10,16 +11,22 @@ const options: Intl.DateTimeFormatOptions = {
1011
day: 'numeric',
1112
hour: 'numeric',
1213
minute: 'numeric',
13-
second: 'numeric',
1414
timeZoneName: 'short',
15+
hour12: true,
1516
};
1617

1718
const DateTime = ({ utcSeconds }: Props) => {
1819
const date = new Date(0); // Use epoch
1920

2021
date.setUTCSeconds(utcSeconds);
2122

22-
return <span>{`${date.toLocaleString('en-GB', options)}`}</span>;
23+
return (
24+
<Tooltip content={`${date.toLocaleString('en-GB', options)}`}>
25+
<span style={{ color: 'rgba(255, 255, 255, 0.4)' }}>
26+
<u>( ... )</u>
27+
</span>
28+
</Tooltip>
29+
);
2330
};
2431

2532
export default DateTime;

src/components/docs/versions/docker-image-link-or-retry-button.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,36 @@
1-
import { Tooltip } from 'antd';
21
import React, { useState } from 'react';
32
import { HiOutlineRefresh } from 'react-icons/hi';
43
import { SimpleAuthCheck } from '@site/src/components/auth/safe-auth-check';
54
import DockerImageLink from '@site/src/components/docs/versions/docker-image-link';
65
import { useAuthenticatedEndpoint } from '@site/src/core/hooks/use-authenticated-endpoint';
76
import { useNotification } from '@site/src/core/hooks/use-notification';
87
import Spinner from '@site/src/components/molecules/spinner';
8+
import Tooltip from '@site/src/components/molecules/tooltip/tooltip';
99

10-
interface Props {
11-
record: {
12-
buildId: string;
13-
relatedJobId: string;
14-
buildInfo: {
15-
baseOs: string;
16-
editorVersion: string;
17-
targetPlatform: string;
18-
repoVersion: string;
19-
};
20-
dockerInfo: {
21-
imageRepo: string;
22-
imageName: string;
23-
};
24-
status: string;
10+
type Record = {
11+
buildId: string;
12+
relatedJobId: string;
13+
buildInfo: {
14+
baseOs: string;
15+
editorVersion: string;
16+
targetPlatform: string;
17+
repoVersion: string;
18+
};
19+
dockerInfo: {
20+
digest: string;
21+
imageRepo: string;
22+
imageName: string;
2523
};
24+
status: string;
25+
[key: string]: any;
26+
};
27+
28+
interface Props {
29+
record: Record;
2630
}
2731

32+
export { Record };
33+
2834
const DockerImageLinkOrRetryButton = ({ record }: Props) => {
2935
const { buildInfo, dockerInfo, buildId, relatedJobId, status } = record;
3036
const { baseOs, editorVersion, targetPlatform, repoVersion } = buildInfo;
@@ -55,7 +61,7 @@ const DockerImageLinkOrRetryButton = ({ record }: Props) => {
5561

5662
return (
5763
<SimpleAuthCheck fallback={<span />} requiredClaims={{ admin: true }}>
58-
<Tooltip title={`Delete tag "${imageTag}" then click this retry button.`}>
64+
<Tooltip content={`Delete tag "${imageTag}" then click this retry button.`}>
5965
<button
6066
type="button"
6167
onClick={onClick}

src/components/docs/versions/docker-image-link.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { SiDocker } from 'react-icons/si';
3+
import Tooltip from '../../molecules/tooltip/tooltip';
34

45
interface Props {
56
imageRepo: string;
@@ -9,17 +10,20 @@ interface Props {
910

1011
const DockerImageLink = ({ imageRepo, imageName, imageTag }: Props) => {
1112
return (
12-
<a
13-
aria-label="Image url"
14-
target="_blank"
15-
rel="noreferrer"
16-
href={
17-
`https://hub.docker.com/repository/docker/${imageRepo}/${imageName}/tags` +
18-
`?page=1&ordering=last_updated&name=${imageTag}`
19-
}
20-
>
21-
<SiDocker />
22-
</a>
13+
<Tooltip content="Dockerhub Image">
14+
<a
15+
aria-label="Image url"
16+
target="_blank"
17+
rel="noreferrer"
18+
href={
19+
`https://hub.docker.com/repository/docker/${imageRepo}/${imageName}/tags` +
20+
`?page=1&ordering=last_updated&name=${imageTag}`
21+
}
22+
className="align-middle ml-2 text-blue-600"
23+
>
24+
<SiDocker />
25+
</a>
26+
</Tooltip>
2327
);
2428
};
2529

0 commit comments

Comments
 (0)