Skip to content

Implement "Dependencies" tab #3346

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 6 commits into from
Mar 1, 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
15 changes: 13 additions & 2 deletions app/components/crate-header.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
<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)
@versionNum
(link "crate.version" @crate @versionNum)
(link "crate.index" @crate)
}}
data-test-readme-tab
Expand All @@ -35,6 +35,17 @@
{{@crate.versions.length}} Versions
</nav.Tab>

<nav.Tab
@link={{if
@versionNum
(link "crate.version-dependencies" @crate @versionNum)
(link "crate.dependencies" @crate)
}}
data-test-deps-tab
>
Dependencies
</nav.Tab>

<nav.Tab @link={{link "crate.reverse-dependencies" @crate}} data-test-rev-deps-tab>
Dependents
</nav.Tab>
Expand Down
1 change: 0 additions & 1 deletion app/components/crate-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ 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')
Expand Down
37 changes: 0 additions & 37 deletions app/components/crate-sidebar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -129,42 +129,5 @@
</div>
{{/if}}
{{/unless}}

<div>
<h3>Dependencies</h3>
<ul data-test-dependencies>
{{#each @version.normalDependencies as |dep|}}
<li><LinkToDep @dep={{dep}} /></li>
{{else}}
{{#if @version.loadDepsTask.isRunning}}
<li>Loading…</li>
{{else}}
<li>None</li>
{{/if}}
{{/each}}
</ul>
</div>

{{#if @version.buildDependencies}}
<div>
<h3>Build-Dependencies</h3>
<ul data-test-build-dependencies>
{{#each @version.buildDependencies as |dep|}}
<li><LinkToDep @dep={{dep}} /></li>
{{/each}}
</ul>
</div>
{{/if}}

{{#if @version.devDependencies}}
<div>
<h3>Dev-Dependencies</h3>
<ul data-test-dev-dependencies>
{{#each @version.devDependencies as |dep|}}
<li><LinkToDep @dep={{dep}} /></li>
{{/each}}
</ul>
</div>
{{/if}}
</div>
</section>
31 changes: 31 additions & 0 deletions app/components/dependency-list/row.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div
local-class="
row
{{if @dependency.optional "optional"}}
{{if this.focused "focused"}}
"
...attributes
>
<span local-class="range" data-test-range>
{{format-req @dependency.req}}
</span>

<span>
<LinkTo
@route="crate"
@model={{@dependency.crate_id}}
local-class="link"
{{on "focusin" (fn this.setFocused true)}}
{{on "focusout" (fn this.setFocused false)}}
data-test-release-track-link
>
{{@dependency.crate_id}}
</LinkTo>

<span local-class="metadata">
{{#if @dependency.optional}}
optional
{{/if}}
</span>
</span>
</div>
11 changes: 11 additions & 0 deletions app/components/dependency-list/row.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

export default class VersionRow extends Component {
@tracked focused = false;

@action setFocused(value) {
this.focused = value;
}
}
100 changes: 100 additions & 0 deletions app/components/dependency-list/row.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
.row {
--bg-color: var(--grey200);
--hover-bg-color: hsl(217, 37%, 98%);
--range-color: var(--grey900);
--crate-color: var(--grey700);
--shadow: 0 1px 3px hsla(51, 90%, 42%, .35);

display: flex;
align-items: center;
position: relative;
font-size: 18px;
padding: 15px 25px;
background-color: white;
border-radius: 7px;
box-shadow: var(--shadow);
transition: all 300ms;

&:hover, &.focused {
background-color: var(--hover-bg-color);
transition: all 0ms;
}

&.focused {
box-shadow: 0 0 0 3px var(--yellow500), var(--shadow);
}

&.optional {
--range-color: var(--grey600);
--crate-color: var(--grey600);
}

[title], :global(.ember-tooltip-target) {
position: relative;
z-index: 1;
cursor: help;
}

:global(.ember-tooltip) {
word-break: break-all;
}

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

.range {
margin-right: 15px;
min-width: 100px;
color: var(--range-color);
font-variant: tabular-nums;
}

.link {
color: var(--crate-color);
font-weight: 500;
margin-right: 15px;
outline: none;

&:hover {
color: var(--crate-color);
}

&::after {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
}

.metadata {
color: var(--grey600);
text-transform: uppercase;
letter-spacing: .7px;
font-size: 13px;

a {
position: relative;
color: var(--grey600);

&:hover {
color: var(--grey900);
}
}

svg {
height: 1em;
width: auto;
margin-right: 2px;
margin-bottom: -.1em;
}

:global(.ember-tooltip) {
text-transform: none;
letter-spacing: normal;
}
}
6 changes: 0 additions & 6 deletions app/components/link-to-dep.hbs

This file was deleted.

3 changes: 0 additions & 3 deletions app/components/link-to-dep.module.css

This file was deleted.

1 change: 1 addition & 0 deletions app/components/nav-tabs/tab.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<a
href={{@link.url}}
local-class="link {{if @link.isActive "active"}}"
data-test-active={{@link.isActive}}
{{on "click" @link.transitionTo}}
>
{{yield}}
Expand Down
2 changes: 2 additions & 0 deletions app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ Router.map(function () {
this.route('crates');
this.route('crate', { path: '/crates/:crate_id' }, function () {
this.route('versions');
this.route('dependencies');
this.route('version', { path: '/:version_num' });
this.route('version-dependencies', { path: '/:version_num/dependencies' });

this.route('reverse-dependencies', { path: 'reverse_dependencies' });

Expand Down
13 changes: 13 additions & 0 deletions app/routes/crate/dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Route from '@ember/routing/route';

export default class VersionRoute extends Route {
async model() {
let crate = this.modelFor('crate');
let versions = await crate.get('versions');

let { defaultVersion } = crate;
let version = versions.find(version => version.num === defaultVersion) ?? versions.lastObject;

this.replaceWith('crate.version-dependencies', crate, version.num);
}
}
34 changes: 34 additions & 0 deletions app/routes/crate/version-dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class VersionRoute extends Route {
@service notifications;

async model(params) {
let crate = this.modelFor('crate');
let versions = await crate.get('versions');

let requestedVersion = params.version_num;
let version = versions.find(version => version.num === requestedVersion);
if (!version) {
this.notifications.error(`Version '${requestedVersion}' of crate '${crate.name}' does not exist`);
this.replaceWith('crate.index');
}

try {
await version.loadDepsTask.perform();
} catch {
this.notifications.error(
`Failed to load the list of dependencies for the '${crate.name}' crate. Please try again later!`,
);
this.replaceWith('crate.index');
}

return version;
}

setupController(controller, model) {
controller.set('version', model);
controller.set('crate', this.modelFor('crate'));
}
}
1 change: 0 additions & 1 deletion app/routes/crate/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export default class VersionRoute extends Route {
setupController(controller, model) {
super.setupController(...arguments);

model.version.loadDepsTask.perform();
if (!model.version.authorNames) {
model.version.loadAuthorsTask.perform();
}
Expand Down
11 changes: 11 additions & 0 deletions app/styles/crate/version-dependencies.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.list {
list-style: none;
margin: 0;
padding: 0;

li {
&:not(:first-child) {
margin-top: 10px;
}
}
}
38 changes: 38 additions & 0 deletions app/templates/crate/version-dependencies.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{{page-title this.crate.name}}

<CrateHeader
@crate={{this.crate}}
@version={{this.version}}
@versionNum={{this.version.num}}
/>

<h3 local-class="heading">Dependencies</h3>
{{#if this.version.normalDependencies}}
<ul local-class="list" data-test-dependencies>
{{#each this.version.normalDependencies as |dependency|}}
<li><DependencyList::Row @dependency={{dependency}} /></li>
{{/each}}
</ul>
{{else}}
<div local-class="no-deps" data-test-no-dependencies>
This version of the "{{this.crate.name}}" crate has no dependencies
</div>
{{/if}}

{{#if this.version.buildDependencies}}
<h3 local-class="heading">Build-Dependencies</h3>
<ul local-class="list" data-test-build-dependencies>
{{#each this.version.buildDependencies as |dependency|}}
<li><DependencyList::Row @dependency={{dependency}} /></li>
{{/each}}
</ul>
{{/if}}

{{#if this.version.devDependencies}}
<h3 local-class="heading">Dev-Dependencies</h3>
<ul local-class="list" data-test-dev-dependencies>
{{#each this.version.devDependencies as |dependency|}}
<li><DependencyList::Row @dependency={{dependency}} /></li>
{{/each}}
</ul>
{{/if}}
6 changes: 5 additions & 1 deletion app/templates/crate/version.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{{page-title this.crate.name}}

<CrateHeader @crate={{this.crate}} @version={{this.currentVersion}} />
<CrateHeader
@crate={{this.crate}}
@version={{this.currentVersion}}
@versionNum={{this.requestedVersion}}
/>

<div local-class='crate-info'>
<div local-class="docs">
Expand Down
Loading