Add breadcrumb navigation
This commit is contained in:
parent
6d4ef48991
commit
9399849e0c
@ -90,7 +90,7 @@ linters:
|
|||||||
style: exclude_zero # or 'include_zero'
|
style: exclude_zero # or 'include_zero'
|
||||||
|
|
||||||
MergeableSelector:
|
MergeableSelector:
|
||||||
enabled: true
|
enabled: false
|
||||||
force_nesting: true
|
force_nesting: true
|
||||||
|
|
||||||
NameFormat:
|
NameFormat:
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
});
|
|
32
app/components/breadcrumb-nav/component.js
Normal file
32
app/components/breadcrumb-nav/component.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import Component from '@ember/component';
|
||||||
|
import EmberObject from '@ember/object';
|
||||||
|
import { isEmpty } from '@ember/utils';
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
|
||||||
|
tagName: 'nav',
|
||||||
|
classNames: ['breadcrumb-nav'],
|
||||||
|
|
||||||
|
currentDirPath: null,
|
||||||
|
|
||||||
|
linkItems: function() {
|
||||||
|
let currentDirPath = this.get('currentDirPath');
|
||||||
|
if (isEmpty(currentDirPath)) { return []; }
|
||||||
|
let linkItems = [];
|
||||||
|
|
||||||
|
let dirs = currentDirPath.split('/')
|
||||||
|
.reject(i => isEmpty(i));
|
||||||
|
|
||||||
|
dirs.forEach(dirname => {
|
||||||
|
let path = currentDirPath.match(`(.*${dirname})/`)[0];
|
||||||
|
|
||||||
|
linkItems.pushObject(EmberObject.create({
|
||||||
|
name: dirname,
|
||||||
|
path: path
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
return linkItems;
|
||||||
|
}.property('currentDirPath')
|
||||||
|
|
||||||
|
});
|
4
app/components/breadcrumb-nav/template.hbs
Normal file
4
app/components/breadcrumb-nav/template.hbs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<span class="node">{{#link-to "index" (query-params path='/')}}Home{{/link-to}}</span>
|
||||||
|
{{#each linkItems as |item|}}
|
||||||
|
<span class="node">{{#link-to "index" (query-params path=item.path)}}{{item.name}}{{/link-to}}</span>
|
||||||
|
{{/each}}
|
@ -1,23 +1,27 @@
|
|||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
|
import { inject as controller } from '@ember/controller';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { alias } from '@ember/object/computed';
|
import { alias } from '@ember/object/computed';
|
||||||
import { isPresent } from '@ember/utils';
|
import { isPresent } from '@ember/utils';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
|
|
||||||
|
application: controller(),
|
||||||
storage: service(),
|
storage: service(),
|
||||||
|
|
||||||
connecting: alias('storage.connecting'),
|
connecting: alias('storage.connecting'),
|
||||||
connected: alias('storage.connected'),
|
connected: alias('storage.connected'),
|
||||||
rootListing: alias('storage.rootListing'),
|
rootListing: alias('storage.rootListing'),
|
||||||
|
currentDirPath: alias('application.currentDirPath'),
|
||||||
|
|
||||||
queryParams: ['path'],
|
queryParams: ['path'],
|
||||||
|
|
||||||
currentListing: function() {
|
currentListing: function() {
|
||||||
if (isPresent(this.get('model'))) {
|
if (isPresent(this.get('model.currentListing'))) {
|
||||||
return this.get('model').sortBy('name');
|
return this.get('model.currentListing').sortBy('name');
|
||||||
|
} else {
|
||||||
|
return this.get('rootListing');
|
||||||
}
|
}
|
||||||
return this.get('rootListing');
|
|
||||||
}.property('rootListing.[]', 'model.[]')
|
}.property('rootListing.[]', 'model.[]')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Route from '@ember/routing/route';
|
import Route from '@ember/routing/route';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { isEmpty } from '@ember/utils';
|
import { isEmpty, isPresent } from '@ember/utils';
|
||||||
|
import { hash } from 'rsvp';
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
|
|
||||||
@ -19,7 +20,10 @@ export default Route.extend({
|
|||||||
|
|
||||||
if (path.substr(-1) !== '/') { path += '/'; }
|
if (path.substr(-1) !== '/') { path += '/'; }
|
||||||
|
|
||||||
return this.get('storage').fetchListing(path);
|
return hash({
|
||||||
|
currentListing: this.get('storage').fetchListing(path),
|
||||||
|
currentDirPath: path
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
@ -28,6 +32,10 @@ export default Route.extend({
|
|||||||
if (isEmpty(this.get('storage.categories')) && this.get('storage.connected')) {
|
if (isEmpty(this.get('storage.categories')) && this.get('storage.connected')) {
|
||||||
this.get('storage').fetchRootListing();
|
this.get('storage').fetchRootListing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPresent(model)) {
|
||||||
|
controller.set('currentDirPath', model.currentDirPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
$dark-grey-1: #2a3743;
|
$dark-grey-1: #2a3743;
|
||||||
$dark-grey-2: #344453;
|
$dark-grey-2: #344453;
|
||||||
|
$dark-grey-3: #aaa;
|
||||||
$light-grey-1: #b5c3d1;
|
$light-grey-1: #b5c3d1;
|
||||||
|
$light-grey-2: #ececec;
|
||||||
|
|
||||||
#app-container {
|
#app-container {
|
||||||
> aside {
|
> aside {
|
||||||
@ -19,5 +21,15 @@ $light-grey-1: #b5c3d1;
|
|||||||
> main {
|
> main {
|
||||||
// background-color: $dark-grey-2;
|
// background-color: $dark-grey-2;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
|
||||||
|
> header {
|
||||||
|
a:link,
|
||||||
|
a:visited {
|
||||||
|
color: $dark-grey-3;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: $dark-grey-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#remotestorage-widget {
|
#remotestorage-widget {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0.5rem;
|
right: 1rem;
|
||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@
|
|||||||
> main {
|
> main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 2rem;
|
padding: 3rem 4rem;
|
||||||
|
|
||||||
> header {
|
> header {
|
||||||
height: 4em;
|
height: 4em;
|
||||||
|
@ -16,6 +16,7 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@import "components/breadcrumb-nav";
|
||||||
@import "components/categories-nav";
|
@import "components/categories-nav";
|
||||||
@import "components/directory-listing";
|
@import "components/directory-listing";
|
||||||
@import "components/item-icon";
|
@import "components/item-icon";
|
||||||
|
22
app/styles/components/_breadcrumb-nav.scss
Normal file
22
app/styles/components/_breadcrumb-nav.scss
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
.breadcrumb-nav {
|
||||||
|
|
||||||
|
a {
|
||||||
|
&.active {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.node {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node + .node {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '›';
|
||||||
|
padding-right: 0.6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,15 +3,17 @@
|
|||||||
ul.listing {
|
ul.listing {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
margin-bottom: 6rem;
|
margin-bottom: 6rem;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: table;
|
display: table;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-bottom: 1px solid #ececec;
|
border-bottom: 1px solid $light-grey-2;
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
border-top: 1px solid #ececec;
|
border-top: 1px solid $light-grey-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -41,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
&.type {
|
&.type {
|
||||||
width: 37%;
|
width: 37%;
|
||||||
color: #aaa;
|
color: $dark-grey-3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,18 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
</aside>
|
</aside>
|
||||||
<main>
|
<main>
|
||||||
|
<header>
|
||||||
|
{{#if connecting}}
|
||||||
|
<!-- Connecting... -->
|
||||||
|
{{else}}
|
||||||
|
{{#if connected}}
|
||||||
|
{{breadcrumb-nav currentDirPath=currentDirPath}}
|
||||||
|
{{else}}
|
||||||
|
Not connected.
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
</header>
|
||||||
|
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
@ -1 +0,0 @@
|
|||||||
{{yield}}
|
|
@ -1,13 +1,3 @@
|
|||||||
<header>
|
|
||||||
{{#if connecting}}
|
|
||||||
<!-- Connecting... -->
|
|
||||||
{{else}}
|
|
||||||
{{#unless connected}}
|
|
||||||
Not connected.
|
|
||||||
{{/unless}}
|
|
||||||
{{/if}}
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{{#if currentListing}}
|
{{#if currentListing}}
|
||||||
{{directory-listing items=currentListing}}
|
{{directory-listing items=currentListing}}
|
||||||
{{/if}}
|
{{/if}}
|
@ -1,24 +0,0 @@
|
|||||||
import { moduleForComponent, test } from 'ember-qunit';
|
|
||||||
import hbs from 'htmlbars-inline-precompile';
|
|
||||||
|
|
||||||
moduleForComponent('breadcrumb-nav', 'Integration | Component | breadcrumb nav', {
|
|
||||||
integration: true
|
|
||||||
});
|
|
||||||
|
|
||||||
test('it renders', function(assert) {
|
|
||||||
// Set any properties with this.set('myProperty', 'value');
|
|
||||||
// Handle any actions with this.on('myAction', function(val) { ... });
|
|
||||||
|
|
||||||
this.render(hbs`{{breadcrumb-nav}}`);
|
|
||||||
|
|
||||||
assert.equal(this.$().text().trim(), '');
|
|
||||||
|
|
||||||
// Template block usage:
|
|
||||||
this.render(hbs`
|
|
||||||
{{#breadcrumb-nav}}
|
|
||||||
template block text
|
|
||||||
{{/breadcrumb-nav}}
|
|
||||||
`);
|
|
||||||
|
|
||||||
assert.equal(this.$().text().trim(), 'template block text');
|
|
||||||
});
|
|
@ -0,0 +1,12 @@
|
|||||||
|
// import { moduleForComponent, test } from 'ember-qunit';
|
||||||
|
// import hbs from 'htmlbars-inline-precompile';
|
||||||
|
//
|
||||||
|
// moduleForComponent('breadcrumb-nav', 'Integration | Component | breadcrumb nav', {
|
||||||
|
// integration: true
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// test('it renders', function(assert) {
|
||||||
|
// this.render(hbs`{{breadcrumb-nav}}`);
|
||||||
|
//
|
||||||
|
// assert.equal(this.$().text().trim(), '');
|
||||||
|
// });
|
Loading…
x
Reference in New Issue
Block a user