Skip to content

Commit b3689ff

Browse files
authored
Merge pull request #172 from ani-team/feature/enchance/misc
Правки с код-ревью
2 parents 9b03a64 + 5429169 commit b3689ff

File tree

13 files changed

+222
-74
lines changed

13 files changed

+222
-74
lines changed

src/features/repo-details/index.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Skeleton, Tag, Alert } from "antd";
1+
import { Skeleton, Tag, Alert, Spin } from "antd";
22
import React from "react";
33
import { Link } from "react-router-dom";
44
import { Language, RepoIdentity } from "../../models";
@@ -33,6 +33,9 @@ const RepoDetails = ({ repo: identity }: Props) => {
3333
const collaborators = repository?.collaborators?.nodes?.filter(
3434
(collaborator): collaborator is Collaborator => !!collaborator,
3535
);
36+
const alertDescription =
37+
"For a while, you can't navigate through file" +
38+
" tree of repo - only view the main README";
3639
return (
3740
<div className="flex flex-col">
3841
<DetailsCard className="common-details" title={identity.name}>
@@ -78,12 +81,14 @@ const RepoDetails = ({ repo: identity }: Props) => {
7881
))}
7982
</DetailsCard>
8083
)}
81-
<Alert
82-
style={{ borderRadius: 6, marginTop: 10 }}
83-
showIcon
84-
message="Files access"
85-
description="For a while, you can't navigate thorugh file tree of repo - only view the main README"
86-
/>
84+
<Spin spinning={loading}>
85+
<Alert
86+
style={{ borderRadius: 6, marginTop: 10 }}
87+
showIcon
88+
message="Files access"
89+
description={alertDescription}
90+
/>
91+
</Spin>
8792
</div>
8893
);
8994
};

src/features/repo-explorer/components/branches-menu/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import "./index.scss";
77
type Props = {
88
repo: RepoIdentity;
99
branches?: Array<BranchIdentity>;
10+
onVisibleChange?: (flag: boolean) => void;
1011
};
1112

12-
const BranchesMenu = ({ repo, branches }: Props) => {
13+
const BranchesMenu = ({ repo, branches, onVisibleChange }: Props) => {
1314
return (
14-
<Menu className="branches-menu" onClick={() => {}}>
15+
<Menu className="branches-menu">
1516
{branches?.map((branch, index) => (
16-
<Menu.Item key={index}>
17+
<Menu.Item key={index} onClick={() => onVisibleChange?.(false)}>
1718
<Link to={`/${repo.owner}/${repo.name}/tree/${branch.name}`}>
1819
{branch.name}
1920
</Link>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from "react";
2+
import { List } from "antd";
3+
import { GITHUB_DOMAIN } from "shared/get-env";
4+
import { RepoIdentity, GitFile } from "models";
5+
import { ReactComponent as FileIcon } from "../../assets/file.svg";
6+
import { ReactComponent as FolderIcon } from "../../assets/folder.svg";
7+
8+
type GitFileViewProps = GitFile & { repo: RepoIdentity; branch: string };
9+
10+
const GitFileView = ({ name, type, repo, branch }: GitFileViewProps) => {
11+
const baseUrl = `${GITHUB_DOMAIN}${repo.owner}/${repo.name}`;
12+
const link = `${baseUrl}/${type}/${branch ? branch + "/" : ""}${name}`;
13+
const EntryIcon = type === "tree" ? FolderIcon : FileIcon;
14+
return (
15+
<List.Item className="repo-git-view__item">
16+
<div className="wrapper">
17+
<EntryIcon className="icon" />
18+
<a href={link} target="_blank" rel="noopener noreferrer" className="origin-link">
19+
{name}
20+
</a>
21+
</div>
22+
</List.Item>
23+
);
24+
};
25+
26+
export default GitFileView;

src/features/repo-explorer/components/entries-view/index.scss

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,16 @@
2121
border-top-left-radius: 5px;
2222
border-top-right-radius: 5px;
2323

24-
@include text-overflow();
24+
.commit-info {
25+
@include text-overflow();
26+
27+
flex: 1 0;
28+
}
29+
30+
span.commit-date {
31+
flex: 0 1;
32+
margin-left: 12px;
33+
}
2534

2635
img,
2736
.avatar-placeholder {
@@ -37,8 +46,7 @@
3746
color: white;
3847
}
3948

40-
span.commit-message,
41-
span.commit-date {
49+
span.commit-message {
4250
margin-left: 5px;
4351
}
4452
}
@@ -47,14 +55,25 @@
4755
padding: 8px 0 8px 8px !important;
4856
border-bottom: 1px solid var(--clr-gray--100) !important;
4957

50-
img {
58+
& > .wrapper {
59+
display: flex;
60+
align-items: center;
61+
}
62+
63+
.icon {
5164
width: 24px;
5265
height: auto;
5366
padding: 4px;
5467
}
5568

56-
span {
69+
.origin-link {
5770
margin-left: 12px;
71+
color: var(--clr-text);
72+
73+
&:hover {
74+
color: #0366d6;
75+
text-decoration: underline;
76+
}
5877
}
5978
}
6079
}
Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,35 @@
11
import React from "react";
2-
import dayjs from "dayjs";
32
import { List } from "antd";
43
import cn from "classnames";
5-
import { Link } from "react-router-dom";
4+
import { RepoIdentity, GitFile, GitCommit } from "models";
5+
import { useBranch } from "../../hooks";
66
import SkeletonArea from "../skeleton-area";
7-
8-
// FIXME: import as ReactComponent
9-
import FileIcon from "../../assets/file.svg";
10-
import FolderIcon from "../../assets/folder.svg";
11-
import logo from "./placeholder.png";
7+
import GitFileView from "./git-file-view";
8+
import LastCommitHeader from "./last-commit-header";
129
import "./index.scss";
1310

14-
type GitFile = { type: string; name: string };
1511
type Props = {
1612
loading?: boolean;
1713
files: Array<GitFile>;
1814
className?: string;
19-
lastCommit?: {
20-
message: string;
21-
login?: string;
22-
avatarUrl?: string;
23-
name?: string | null;
24-
date: string;
25-
};
15+
repo: RepoIdentity;
16+
lastCommit?: GitCommit;
2617
};
2718

28-
const EntriesView = ({ loading, files, lastCommit, className }: Props) => {
19+
const EntriesView = ({ loading, files, lastCommit, className, repo }: Props) => {
20+
const { branch } = useBranch(repo);
2921
return (
3022
<div className={cn("repo-git-view", className)}>
3123
{loading && <SkeletonArea />}
3224
{!loading && (
3325
<List
3426
header={lastCommit && <LastCommitHeader lastCommit={lastCommit} />}
3527
dataSource={files}
36-
renderItem={GitFileView}
28+
renderItem={(item) => <GitFileView {...item} repo={repo} branch={branch} />}
3729
/>
3830
)}
3931
</div>
4032
);
4133
};
4234

43-
const GitFileView = ({ name, type }: GitFile) => (
44-
<List.Item className="repo-git-view__item">
45-
<div>
46-
<img alt="type" src={type === "tree" ? FolderIcon : FileIcon} />
47-
<span>{name}</span>
48-
</div>
49-
</List.Item>
50-
);
51-
52-
const LastCommitHeader = ({ lastCommit }: { lastCommit: Props["lastCommit"] }) => (
53-
<div className="repo-git-view__last-commit">
54-
<div>
55-
{lastCommit?.avatarUrl ? (
56-
<>
57-
<img src={lastCommit?.avatarUrl} alt="avatar" />
58-
<Link className="author-name" to={`/${lastCommit?.login}`}>
59-
{lastCommit?.login}
60-
</Link>
61-
</>
62-
) : (
63-
<>
64-
<img src={logo} alt="avatar" />
65-
<span className="author-name">{lastCommit?.name}</span>
66-
</>
67-
)}
68-
&nbsp;
69-
<span className="commit-message" title={lastCommit?.message}>
70-
{lastCommit?.message}
71-
</span>
72-
</div>
73-
<div>
74-
<span className="commit-date">on {dayjs(lastCommit?.date).format("D MMM YYYY")}</span>
75-
</div>
76-
</div>
77-
);
78-
7935
export default EntriesView;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from "react";
2+
import dayjs from "dayjs";
3+
import { Link } from "react-router-dom";
4+
import { GitCommit } from "models";
5+
import logo from "./placeholder.png";
6+
7+
type Props = {
8+
lastCommit: GitCommit;
9+
};
10+
11+
const LastCommitHeader = ({ lastCommit }: Props) => {
12+
const { login, name, avatarUrl, message, date } = lastCommit || {};
13+
return (
14+
<div className="repo-git-view__last-commit">
15+
<div className="commit-info">
16+
<img src={avatarUrl ?? logo} alt="avatar" />
17+
{avatarUrl ? (
18+
<Link className="author-name" to={`/${login}`}>
19+
{login}
20+
</Link>
21+
) : (
22+
<span className="author-name">{name}</span>
23+
)}
24+
&nbsp;
25+
<span className="commit-message" title={message}>
26+
{message}
27+
</span>
28+
</div>
29+
<div>
30+
<span className="commit-date">on {dayjs(date).format("D MMM YYYY")}</span>
31+
</div>
32+
</div>
33+
);
34+
};
35+
36+
export default LastCommitHeader;

src/features/repo-explorer/components/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ const Explorer = ({ repo }: Props) => {
2828
return (
2929
<div>
3030
<RepoToolbar repo={repo} branches={branches} activeBranch={branch} />
31-
<EntriesView files={files} lastCommit={lastCommit} loading={loading} className="mt-3" />
31+
<EntriesView
32+
files={files}
33+
lastCommit={lastCommit}
34+
loading={loading}
35+
repo={repo}
36+
className="mt-3"
37+
/>
3238
<RepoReadme text={readme} loading={loading} repoUrl={repoUrl} branch={branch} />
3339
</div>
3440
);

src/features/repo-explorer/components/toolbar/index.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Button, Dropdown, Popover } from "antd";
2-
import React from "react";
2+
import React, { useState } from "react";
33
import { RepoIdentity, BranchIdentity } from "models";
44
import BranchesMenu from "../branches-menu";
55
import CloneMenu from "./clone-menu";
@@ -12,12 +12,21 @@ type Props = {
1212
};
1313

1414
const RepoToolbar = ({ repo, branches, activeBranch }: Props) => {
15+
const [isBranchDropdownVisible, setBranchDropdownVisible] = useState(false);
1516
return (
1617
<div className="flex justify-between">
1718
<Dropdown
18-
overlay={<BranchesMenu branches={branches} repo={repo} />}
19+
overlay={
20+
<BranchesMenu
21+
branches={branches}
22+
repo={repo}
23+
onVisibleChange={setBranchDropdownVisible}
24+
/>
25+
}
1926
placement="bottomLeft"
2027
arrow
28+
visible={isBranchDropdownVisible}
29+
onVisibleChange={setBranchDropdownVisible}
2130
trigger={["click"]}
2231
>
2332
<Button className="branch-dropdown">{activeBranch}</Button>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { BranchIdentity, RepoIdentity } from "models";
2+
import { RepoBranchInfoQuery, useRepoDefaultBranchQuery } from "./queries.gen";
3+
4+
/**
5+
* @hook Получение текущей ветки репозитория
6+
*/
7+
export const useBranch = (repo: RepoIdentity) => {
8+
const { data } = useRepoDefaultBranchQuery({
9+
variables: {
10+
name: repo.name,
11+
owner: repo.owner,
12+
},
13+
});
14+
const branch = repo.branch || data?.repository?.defaultBranchRef?.name || "master";
15+
return { branch };
16+
};
17+
18+
/**
19+
* @hook Получение нужных полей по сфетченным данным по репозиторию
20+
*/
21+
export const useRepoDetails = (repoInfo: RepoBranchInfoQuery | undefined) => {
22+
const { repository } = repoInfo || {};
23+
const branches = (repository?.refs?.nodes || []).filter(
24+
(branch): branch is BranchIdentity => !!branch,
25+
);
26+
const files = Array.from(repository?.object?.entries ?? []).sort((a, b) =>
27+
b.type.localeCompare(a.type),
28+
);
29+
const target = repository?.ref?.target;
30+
const lastCommit =
31+
(target && {
32+
message: target.messageHeadline,
33+
login: target.author?.user?.login,
34+
avatarUrl: target.author?.user?.avatarUrl,
35+
name: target.author?.name,
36+
date: target.author?.date,
37+
}) ||
38+
undefined;
39+
40+
// Приходится фетчить файл по двум вариантам наименования, т.к. GitHub не умеет в insensitive case =(
41+
const readme = repository?.contentLower?.text || repository?.contentUpper?.text || "";
42+
return {
43+
branches,
44+
files,
45+
lastCommit,
46+
readme,
47+
};
48+
};

src/features/repo-stat/index.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,14 @@
4545
border-bottom-right-radius: var(--radius);
4646
}
4747
}
48+
49+
&__skeleton.ant-skeleton-element {
50+
flex-basis: 30%;
51+
width: 30%;
52+
border-radius: var(--radius);
53+
54+
& > span {
55+
width: 100%;
56+
}
57+
}
4858
}

0 commit comments

Comments
 (0)