Skip to content

Commit 48f7a8e

Browse files
committed
Extract CrateSidebar component
1 parent 2b3bdf1 commit 48f7a8e

File tree

6 files changed

+254
-237
lines changed

6 files changed

+254
-237
lines changed

app/components/crate-sidebar.hbs

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<section
2+
local-class='authorship'
3+
aria-label="Crate metadata"
4+
...attributes
5+
>
6+
<div local-class='top'>
7+
<div>
8+
<div local-class='last-update'>Last Updated</div>
9+
<div local-class='{{if @version.crate_size 'date-with-small-margin-bot' 'date'}}'>{{moment-from-now @crate.updated_at}}</div>
10+
</div>
11+
12+
{{#if @version.crate_size}}
13+
<div>
14+
<div local-class='crate-size'>Crate Size</div>
15+
<div local-class='size'>{{pretty-bytes @version.crate_size}}</div>
16+
</div>
17+
{{/if}}
18+
19+
<div>
20+
<h3>Owners</h3>
21+
22+
{{#if this.isOwner}}
23+
<p>
24+
<LinkTo @route="crate.owners" @model={{@crate}} data-test-manage-owners-link>
25+
Manage owners
26+
</LinkTo>
27+
</p>
28+
{{/if}}
29+
30+
<ul local-class='owners' data-test-owners>
31+
{{#each @crate.owner_team as |team|}}
32+
<li>
33+
<LinkTo @route={{team.kind}} @model={{team.login}} data-test-team-link={{team.login}}>
34+
<UserAvatar @user={{team}} @size="medium-small" />
35+
</LinkTo>
36+
</li>
37+
{{/each}}
38+
39+
{{#each @crate.owner_user as |user|}}
40+
<li>
41+
<LinkTo @route={{user.kind}} @model={{user.login}} data-test-user-link={{user.login}}>
42+
<UserAvatar @user={{user}} @size="medium-small" />
43+
</LinkTo>
44+
</li>
45+
{{/each}}
46+
</ul>
47+
</div>
48+
49+
<div>
50+
<h3>Authors</h3>
51+
<ul>
52+
{{#each @version.authorNames as |author|}}
53+
<li>{{ format-email author }}</li>
54+
{{/each}}
55+
</ul>
56+
</div>
57+
</div>
58+
59+
<div local-class='bottom'>
60+
{{#if @version.license}}
61+
<div>
62+
<h3>License</h3>
63+
<p data-test-license>{{ @version.license }}</p>
64+
</div>
65+
{{/if}}
66+
67+
{{#unless @crate.keywords.isPending}}
68+
{{#if @crate.keywords}}
69+
<div>
70+
<h3>Keywords</h3>
71+
<ul local-class='keywords'>
72+
{{#each @crate.keywords as |keyword|}}
73+
<li><LinkTo @route="keyword" @model={{keyword}}>{{keyword.id}}</LinkTo></li>
74+
{{/each}}
75+
</ul>
76+
</div>
77+
{{/if}}
78+
{{/unless}}
79+
80+
{{#unless @crate.categories.isPending}}
81+
{{#if @crate.categories}}
82+
<div>
83+
<h3>Categories</h3>
84+
<ul>
85+
{{#each @crate.categories as |category|}}
86+
<li><LinkTo @route="category" @model={{category.slug}}>{{category.category}}</LinkTo></li>
87+
{{/each}}
88+
</ul>
89+
</div>
90+
{{/if}}
91+
{{/unless}}
92+
93+
<div data-test-versions>
94+
<h3>Versions</h3>
95+
<ul>
96+
{{#each this.smallSortedVersions as |version|}}
97+
<li>
98+
<LinkTo @route="crate.version" @model={{version.num}} data-test-version-link={{version.num}}>
99+
{{ version.num }}
100+
</LinkTo>
101+
{{date-format version.created_at "PP"}}
102+
{{#if version.yanked}}
103+
<span local-class='yanked'>yanked</span>
104+
{{/if}}
105+
</li>
106+
{{/each}}
107+
</ul>
108+
{{#if this.hasMoreVersions}}
109+
<LinkTo @route="crate.versions" @model={{@crate}} local-class="more-versions-link" data-test-all-versions-link>
110+
show all {{ @crate.versions.length }} versions
111+
</LinkTo>
112+
{{/if}}
113+
</div>
114+
115+
<div>
116+
<h3>Dependencies</h3>
117+
<ul data-test-dependencies>
118+
{{#each @version.normalDependencies as |dep|}}
119+
<li><LinkToDep @dep={{dep}} /></li>
120+
{{else}}
121+
{{#if @version.loadDepsTask.isRunning}}
122+
<li>Loading…</li>
123+
{{else}}
124+
<li>None</li>
125+
{{/if}}
126+
{{/each}}
127+
</ul>
128+
</div>
129+
130+
{{#if @version.buildDependencies}}
131+
<div>
132+
<h3>Build-Dependencies</h3>
133+
<ul data-test-build-dependencies>
134+
{{#each @version.buildDependencies as |dep|}}
135+
<li><LinkToDep @dep={{dep}} /></li>
136+
{{/each}}
137+
</ul>
138+
</div>
139+
{{/if}}
140+
141+
{{#if @version.devDependencies}}
142+
<div>
143+
<h3>Dev-Dependencies</h3>
144+
<ul data-test-dev-dependencies>
145+
{{#each @version.devDependencies as |dep|}}
146+
<li><LinkToDep @dep={{dep}} /></li>
147+
{{/each}}
148+
</ul>
149+
</div>
150+
{{/if}}
151+
</div>
152+
</section>

app/components/crate-sidebar.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { computed } from '@ember/object';
2+
import { gt, readOnly } from '@ember/object/computed';
3+
import { inject as service } from '@ember/service';
4+
import Component from '@glimmer/component';
5+
6+
const NUM_VERSIONS = 5;
7+
8+
export default class DownloadGraph extends Component {
9+
@service session;
10+
11+
@computed('args.crate.owner_user', 'session.currentUser.id')
12+
get isOwner() {
13+
return this.args.crate.owner_user.findBy('id', this.session.currentUser?.id);
14+
}
15+
16+
@readOnly('args.crate.versions') sortedVersions;
17+
18+
@computed('sortedVersions')
19+
get smallSortedVersions() {
20+
return this.sortedVersions.slice(0, NUM_VERSIONS);
21+
}
22+
23+
@gt('sortedVersions.length', NUM_VERSIONS) hasMoreVersions;
24+
}
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
.authorship {
2+
.top, .bottom {
3+
display: flex;
4+
flex-wrap: wrap;
5+
6+
> * { margin-right: 1em; }
7+
}
8+
9+
.top > * { flex: 1 }
10+
11+
@media only screen and (min-width: 890px) {
12+
flex: 3;
13+
border-left: 2px solid var(--gray-border);
14+
padding-left: 20px;
15+
16+
.top, .bottom {
17+
flex-direction: column;
18+
}
19+
20+
ul {
21+
padding-left: 20px;
22+
}
23+
}
24+
25+
@media only screen and (max-width: 480px) {
26+
.top, .bottom {
27+
flex-direction: column;
28+
}
29+
}
30+
}
31+
32+
.last-update,
33+
.crate-size {
34+
composes: small from '../styles/shared/typography.module.css';
35+
line-height: 25px;
36+
}
37+
38+
.date {
39+
font-weight: bold;
40+
margin-bottom: 40px;
41+
}
42+
43+
/*
44+
Since crate_size is a new field, older crates won't have it.
45+
Preserve behaviour for older crates. For newer ones, keep
46+
`Crate Size` closer to last updated.
47+
*/
48+
.date-with-small-margin-bot {
49+
font-weight: bold;
50+
margin-bottom: 20px;
51+
}
52+
53+
.size {
54+
font-weight: bold;
55+
margin-bottom: 40px;
56+
}
57+
58+
ul.owners, ul.keywords {
59+
display: flex;
60+
flex-wrap: wrap;
61+
list-style: none;
62+
padding: 0;
63+
margin: 0;
64+
65+
li {
66+
margin: 0 7px 7px 0;
67+
}
68+
}
69+
70+
.yanked {
71+
composes: yanked from '../styles/shared/typography.module.css';
72+
}
73+
74+
.more-versions-link {
75+
composes: small from '../styles/shared/typography.module.css';
76+
}

app/controllers/crate/version.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Controller from '@ember/controller';
22
import { computed } from '@ember/object';
3-
import { alias, gt, readOnly } from '@ember/object/computed';
3+
import { alias, readOnly } from '@ember/object/computed';
44
import { inject as service } from '@ember/service';
55

66
import subDays from 'date-fns/subDays';
@@ -21,8 +21,6 @@ export default class CrateVersionController extends Controller {
2121
@alias('model.crate') crate;
2222
@alias('model.requestedVersion') requestedVersion;
2323
@alias('model.version') currentVersion;
24-
@alias('crate.keywords') keywords;
25-
@alias('crate.categories') categories;
2624

2725
@computed('crate.owner_user', 'session.currentUser.id')
2826
get isOwner() {
@@ -36,10 +34,6 @@ export default class CrateVersionController extends Controller {
3634
return this.sortedVersions.slice(0, NUM_VERSIONS);
3735
}
3836

39-
@gt('sortedVersions.length', NUM_VERSIONS) hasMoreVersions;
40-
@gt('keywords.length', 0) anyKeywords;
41-
@gt('categories.length', 0) anyCategories;
42-
4337
@computed('downloads', 'extraDownloads', 'requestedVersion')
4438
get downloadData() {
4539
let downloads = this.downloads;

app/styles/crate/version.module.css

-80
Original file line numberDiff line numberDiff line change
@@ -113,82 +113,6 @@ div.header {
113113
}
114114
}
115115

116-
.last-update,
117-
.crate-size {
118-
composes: small from '../shared/typography.module.css';
119-
line-height: 25px;
120-
}
121-
122-
.date {
123-
font-weight: bold;
124-
margin-bottom: 40px;
125-
}
126-
127-
/*
128-
Since crate_size is a new field, older crates won't have it.
129-
Preserve behaviour for older crates. For newer ones, keep
130-
`Crate Size` closer to last updated.
131-
*/
132-
.date-with-small-margin-bot {
133-
font-weight: bold;
134-
margin-bottom: 20px;
135-
}
136-
137-
.size {
138-
font-weight: bold;
139-
margin-bottom: 40px;
140-
}
141-
142-
.crate-info .authorship {
143-
ul.owners, ul.keywords {
144-
display: flex;
145-
flex-wrap: wrap;
146-
list-style: none;
147-
padding: 0;
148-
margin: 0;
149-
150-
li {
151-
margin: 0 7px 7px 0;
152-
}
153-
}
154-
}
155-
156-
.more-versions-link {
157-
composes: small from '../shared/typography.module.css';
158-
}
159-
160-
.authorship {
161-
.top, .bottom {
162-
display: flex;
163-
flex-wrap: wrap;
164-
165-
> * { margin-right: 1em; }
166-
}
167-
168-
.top > * { flex: 1 }
169-
170-
@media only screen and (min-width: 890px) {
171-
flex: 3;
172-
border-left: 2px solid var(--gray-border);
173-
padding-left: 20px;
174-
175-
.top, .bottom {
176-
flex-direction: column;
177-
}
178-
179-
ul {
180-
padding-left: 20px;
181-
}
182-
}
183-
184-
@media only screen and (max-width: 480px) {
185-
.top, .bottom {
186-
flex-direction: column;
187-
}
188-
}
189-
}
190-
191-
192116
.about {
193117
line-height: 180%;
194118
margin-bottom: 40px;
@@ -250,7 +174,3 @@ div.header {
250174
display: none;
251175
}
252176
}
253-
254-
.yanked {
255-
composes: yanked from '../shared/typography.module.css';
256-
}

0 commit comments

Comments
 (0)