Skip to content

Add navigation tabs to the crate details pages #3330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion app/components/crate-header.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,31 @@
<FollowButton @crate={{@crate}}/>
{{/if}}
</div>
</PageHeader>
</PageHeader>

<NavTabs aria-label="{{@crate.name}} crate subpages" local-class="nav" as |nav|>
<nav.Tab
@link={{if
(eq this.router.currentRouteName "crate.version")
(link "crate.version" @crate @version.num)
(link "crate.index" @crate)
}}
data-test-readme-tab
>
Readme
</nav.Tab>

<nav.Tab @link={{link "crate.versions" @crate}} data-test-versions-tab>
{{@crate.versions.length}} Versions
</nav.Tab>

<nav.Tab @link={{link "crate.reverse-dependencies" @crate}} data-test-rev-deps-tab>
Dependents
</nav.Tab>

{{#if this.isOwner}}
<nav.Tab @link={{link "crate.owners" @crate}} data-test-settings-tab>
Settings
</nav.Tab>
{{/if}}
</NavTabs>
7 changes: 7 additions & 0 deletions app/components/crate-header.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import Component from '@glimmer/component';

export default class CrateHeader extends Component {
@service router;
@service session;

@computed('args.crate.owner_user', 'session.currentUser.id')
get isOwner() {
return this.args.crate.owner_user.findBy('id', this.session.currentUser?.id);
}
}
4 changes: 4 additions & 0 deletions app/components/crate-header.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@
width: 32px;
height: 32px;
}

.nav {
margin-bottom: 20px;
}
34 changes: 0 additions & 34 deletions app/components/crate-sidebar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,6 @@
<div>
<h3>Owners</h3>

{{#if this.isOwner}}
<p>
<LinkTo @route="crate.owners" @model={{@crate}} data-test-manage-owners-link>
Manage owners
</LinkTo>
</p>
{{/if}}

<ul local-class='owners' data-test-owners>
{{#each @crate.owner_team as |team|}}
<li>
Expand Down Expand Up @@ -152,28 +144,6 @@
{{/if}}
{{/unless}}

<div data-test-versions>
<h3>Versions</h3>
<ul>
{{#each this.smallSortedVersions as |version|}}
<li>
<LinkTo @route="crate.version" @model={{version.num}} data-test-version-link={{version.num}}>
{{ version.num }}
</LinkTo>
{{date-format version.created_at "PP"}}
{{#if version.yanked}}
<span local-class='yanked'>yanked</span>
{{/if}}
</li>
{{/each}}
</ul>
{{#if this.hasMoreVersions}}
<LinkTo @route="crate.versions" @model={{@crate}} local-class="more-versions-link" data-test-all-versions-link>
show all {{ @crate.versions.length }} versions
</LinkTo>
{{/if}}
</div>

<div>
<h3>Dependencies</h3>
<ul data-test-dependencies>
Expand All @@ -187,10 +157,6 @@
{{/if}}
{{/each}}
</ul>

<LinkTo @route="crate.reverse-dependencies" local-class="reverse-deps-link" data-test-reverse-deps-link>
Show dependent crates
</LinkTo>
</div>

{{#if @version.buildDependencies}}
Expand Down
8 changes: 0 additions & 8 deletions app/components/crate-sidebar.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import { computed } from '@ember/object';
import { gt, readOnly } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import Component from '@glimmer/component';

const NUM_VERSIONS = 5;

export default class DownloadGraph extends Component {
@service session;

@computed('args.crate.owner_user', 'session.currentUser.id')
get isOwner() {
return this.args.crate.owner_user.findBy('id', this.session.currentUser?.id);
}

@readOnly('args.crate.versions') sortedVersions;

@computed('sortedVersions')
Expand Down
5 changes: 5 additions & 0 deletions app/components/nav-tabs.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<nav ...attributes>
<ul local-class="list">
{{yield (hash Tab=(component "nav-tabs/tab"))}}
</ul>
</nav>
18 changes: 18 additions & 0 deletions app/components/nav-tabs.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.list {
--nav-tabs-border-width: 2px;
--nav-tabs-padding-h: 20px;
--nav-tabs-padding-v: 12px;
--nav-tabs-radius: 5px;

display: flex;
list-style: none;
padding: 0;
margin: 0;
border-bottom: var(--nav-tabs-border-width) solid var(--gray-border);

@media only screen and (max-width: 550px) {
flex-direction: column;
border-left: var(--nav-tabs-border-width) solid var(--gray-border);
border-bottom: none;
}
}
9 changes: 9 additions & 0 deletions app/components/nav-tabs/tab.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<li ...attributes>
<a
href={{@link.url}}
local-class="link {{if @link.isActive "active"}}"
{{on "click" @link.transitionTo}}
>
{{yield}}
</a>
</li>
45 changes: 45 additions & 0 deletions app/components/nav-tabs/tab.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.link {
display: block;
padding:
calc(var(--nav-tabs-padding-v) + var(--nav-tabs-border-width))
var(--nav-tabs-padding-h)
var(--nav-tabs-padding-v);
color: var(--main-color);
border-top-left-radius: var(--nav-tabs-radius);
border-top-right-radius: var(--nav-tabs-radius);
border-bottom: var(--nav-tabs-border-width) solid transparent;
margin-bottom: calc(0px - var(--nav-tabs-border-width));
transition: all 300ms;

&.active {
color: var(--link-hover-color);
border-bottom-color: var(--link-hover-color);
background: var(--main-bg-dark);
}

&:hover {
color: var(--link-hover-color);
border-bottom-color: var(--link-hover-color);
transition: all 0s;
}

@media only screen and (max-width: 550px) {
padding:
var(--nav-tabs-padding-v)
var(--nav-tabs-padding-h)
var(--nav-tabs-padding-v)
calc(var(--nav-tabs-padding-h) + var(--nav-tabs-border-width));

border-top-left-radius: 0;
border-bottom-right-radius: var(--nav-tabs-radius);
border-bottom: none;
border-left: var(--nav-tabs-border-width) solid transparent;
margin-bottom: 0;
margin-left: calc(0px - var(--nav-tabs-border-width));

&.active,
&:hover {
border-left-color: var(--link-hover-color);
}
}
}
9 changes: 9 additions & 0 deletions app/styles/crate/versions.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@
align-items: center;
justify-content: space-between;
margin-bottom: 10px;

@media only screen and (max-width: 550px) {
display: block;
}
}

.page-description {
composes: small from '../shared/typography.module.css';

@media only screen and (max-width: 550px) {
display: block;
margin-bottom: 15px;
}
}

.list {
Expand Down
6 changes: 1 addition & 5 deletions app/templates/crate/owners.hbs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
{{page-title 'Manage Crate Owners'}}

<PageHeader
@title="Manage Crate Owners"
@suffix={{this.crate.name}}
@icon="gear"
/>
<CrateHeader @crate={{this.crate}} />

<div local-class="me-email">
<h2>Add Owner</h2>
Expand Down
4 changes: 0 additions & 4 deletions app/templates/crate/reverse-dependencies.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<CrateHeader @crate={{this.crate}} />

<div local-class="back-link">
<LinkTo @route="crate" @model={{this.crate.id}}>&#11013; Back to {{ this.crate.name }}</LinkTo>
</div>

<div local-class="results-meta">
<ResultsCount
@start={{this.pagination.currentPageStart}}
Expand Down
14 changes: 5 additions & 9 deletions app/templates/crate/versions.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<CrateHeader @crate={{this.model}} />

<div local-class="results-meta">
<LinkTo @route="crate" @model={{this.model}} local-class="back-link">
&#11013; Back to Main Page
</LinkTo>
<span local-class="page-description" data-test-page-description>
All <strong>{{ this.model.versions.length }}</strong>
versions of <strong>{{ this.model.name }}</strong> since
{{date-format this.model.created_at 'PPP'}}
</span>

<div data-test-search-sort>
<span local-class="sort-by-label">Sort by </span>
Expand All @@ -14,12 +16,6 @@
</div>
</div>

<span local-class="page-description" data-test-page-description>
All <strong>{{ this.model.versions.length }}</strong>
versions of <strong>{{ this.model.name }}</strong> since
{{date-format this.model.created_at 'PPP'}}
</span>

<ul local-class="list">
{{#each this.sortedVersions as |version|}}
<li>
Expand Down
12 changes: 6 additions & 6 deletions tests/acceptance/crate-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ module('Acceptance | crate page', function (hooks) {
this.server.loadFixtures();

await visit('/crates/nanomsg');
await click('[data-test-all-versions-link]');
await click('[data-test-versions-tab] a');

assert.dom('[data-test-page-description]').hasText(/All 13\s+versions of nanomsg since\s+December \d+th, 2014/);
});
Expand All @@ -106,7 +106,7 @@ module('Acceptance | crate page', function (hooks) {
this.server.loadFixtures();

await visit('/crates/nanomsg');
await click('[data-test-reverse-deps-link]');
await click('[data-test-rev-deps-tab] a');

assert.equal(currentURL(), '/crates/nanomsg/reverse_dependencies');
assert.dom('a[href="/crates/unicorn-rpc"]').hasText('unicorn-rpc');
Expand Down Expand Up @@ -183,7 +183,7 @@ module('Acceptance | crate page', function (hooks) {
await visit('/crates/nanomsg');
assert.dom('[data-test-license]').hasText('Apache-2.0');

await click('[data-test-version-link="0.5.0"]');
await visit('/crates/nanomsg/0.5.0');
assert.dom('[data-test-license]').hasText('MIT OR Apache-2.0');
});

Expand Down Expand Up @@ -211,7 +211,7 @@ module('Acceptance | crate page', function (hooks) {

await visit('/crates/nanomsg');

assert.dom('[data-test-manage-owners-link]').doesNotExist();
assert.dom('[data-test-settings-tab]').doesNotExist();
});

test('navigating to the owners page when not an owner', async function (assert) {
Expand All @@ -222,7 +222,7 @@ module('Acceptance | crate page', function (hooks) {

await visit('/crates/nanomsg');

assert.dom('[data-test-manage-owners-link]').doesNotExist();
assert.dom('[data-test-settings-tab]').doesNotExist();
});

test('navigating to the owners page', async function (assert) {
Expand All @@ -232,7 +232,7 @@ module('Acceptance | crate page', function (hooks) {
this.authenticateAs(user);

await visit('/crates/nanomsg');
await click('[data-test-manage-owners-link]');
await click('[data-test-settings-tab] a');

assert.equal(currentURL(), '/crates/nanomsg/owners');
});
Expand Down