Add breadcrumb navigation
This commit is contained in:
parent
6d4ef48991
commit
9399849e0c
|
@ -90,7 +90,7 @@ linters:
|
|||
style: exclude_zero # or 'include_zero'
|
||||
|
||||
MergeableSelector:
|
||||
enabled: true
|
||||
enabled: false
|
||||
force_nesting: true
|
||||
|
||||
NameFormat:
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
});
|
|
@ -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')
|
||||
|
||||
});
|
|
@ -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 { inject as controller } from '@ember/controller';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { alias } from '@ember/object/computed';
|
||||
import { isPresent } from '@ember/utils';
|
||||
|
||||
export default Controller.extend({
|
||||
|
||||
application: controller(),
|
||||
storage: service(),
|
||||
|
||||
connecting: alias('storage.connecting'),
|
||||
connected: alias('storage.connected'),
|
||||
rootListing: alias('storage.rootListing'),
|
||||
currentDirPath: alias('application.currentDirPath'),
|
||||
|
||||
queryParams: ['path'],
|
||||
|
||||
currentListing: function() {
|
||||
if (isPresent(this.get('model'))) {
|
||||
return this.get('model').sortBy('name');
|
||||
if (isPresent(this.get('model.currentListing'))) {
|
||||
return this.get('model.currentListing').sortBy('name');
|
||||
} else {
|
||||
return this.get('rootListing');
|
||||
}
|
||||
return this.get('rootListing');
|
||||
}.property('rootListing.[]', 'model.[]')
|
||||
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Route from '@ember/routing/route';
|
||||
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({
|
||||
|
||||
|
@ -19,7 +20,10 @@ export default Route.extend({
|
|||
|
||||
if (path.substr(-1) !== '/') { path += '/'; }
|
||||
|
||||
return this.get('storage').fetchListing(path);
|
||||
return hash({
|
||||
currentListing: this.get('storage').fetchListing(path),
|
||||
currentDirPath: path
|
||||
});
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
|
@ -28,6 +32,10 @@ export default Route.extend({
|
|||
if (isEmpty(this.get('storage.categories')) && this.get('storage.connected')) {
|
||||
this.get('storage').fetchRootListing();
|
||||
}
|
||||
|
||||
if (isPresent(model)) {
|
||||
controller.set('currentDirPath', model.currentDirPath);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
$dark-grey-1: #2a3743;
|
||||
$dark-grey-2: #344453;
|
||||
$dark-grey-3: #aaa;
|
||||
$light-grey-1: #b5c3d1;
|
||||
$light-grey-2: #ececec;
|
||||
|
||||
#app-container {
|
||||
> aside {
|
||||
|
@ -19,5 +21,15 @@ $light-grey-1: #b5c3d1;
|
|||
> main {
|
||||
// background-color: $dark-grey-2;
|
||||
background-color: #fff;
|
||||
|
||||
> header {
|
||||
a:link,
|
||||
a:visited {
|
||||
color: $dark-grey-3;
|
||||
}
|
||||
a:hover {
|
||||
color: $dark-grey-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#remotestorage-widget {
|
||||
position: fixed;
|
||||
right: 0.5rem;
|
||||
right: 1rem;
|
||||
top: 0.5rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
|||
> main {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 2rem;
|
||||
padding: 3rem 4rem;
|
||||
|
||||
> header {
|
||||
height: 4em;
|
||||
|
|
|
@ -16,6 +16,7 @@ body {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
@import "components/breadcrumb-nav";
|
||||
@import "components/categories-nav";
|
||||
@import "components/directory-listing";
|
||||
@import "components/item-icon";
|
||||
|
|
|
@ -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 {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 6rem;
|
||||
|
||||
li {
|
||||
display: table;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #ececec;
|
||||
border-bottom: 1px solid $light-grey-2;
|
||||
|
||||
&:first-of-type {
|
||||
border-top: 1px solid #ececec;
|
||||
border-top: 1px solid $light-grey-2;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
@ -41,7 +43,7 @@
|
|||
}
|
||||
&.type {
|
||||
width: 37%;
|
||||
color: #aaa;
|
||||
color: $dark-grey-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,18 @@
|
|||
{{/if}}
|
||||
</aside>
|
||||
<main>
|
||||
<header>
|
||||
{{#if connecting}}
|
||||
<!-- Connecting... -->
|
||||
{{else}}
|
||||
{{#if connected}}
|
||||
{{breadcrumb-nav currentDirPath=currentDirPath}}
|
||||
{{else}}
|
||||
Not connected.
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</header>
|
||||
|
||||
{{outlet}}
|
||||
</main>
|
||||
</div>
|
|
@ -1 +0,0 @@
|
|||
{{yield}}
|
|
@ -1,13 +1,3 @@
|
|||
<header>
|
||||
{{#if connecting}}
|
||||
<!-- Connecting... -->
|
||||
{{else}}
|
||||
{{#unless connected}}
|
||||
Not connected.
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</header>
|
||||
|
||||
{{#if currentListing}}
|
||||
{{directory-listing items=currentListing}}
|
||||
{{/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…
Reference in New Issue