Set up responsive admin layout

This commit is contained in:
Toby Zerner 2015-03-30 12:46:55 +10:30
parent 4678603f55
commit 8e3186d41c
22 changed files with 257 additions and 23 deletions

View File

@ -0,0 +1,8 @@
import Ember from 'ember';
import NavItem from './nav-item';
var precompileTemplate = Ember.Handlebars.compile;
export default NavItem.extend({
layout: precompileTemplate('{{#link-to routeName}}{{fa-icon icon class="icon"}} <span class="label">{{label}}</span> <div class="description">{{description}}</div>{{/link-to}}')
});

View File

@ -0,0 +1,23 @@
import Ember from 'ember';
import HasItemLists from '../mixins/has-item-lists';
import DropdownButton from './ui/dropdown-button';
var precompileTemplate = Ember.Handlebars.compile;
export default DropdownButton.extend(HasItemLists, {
layoutName: 'components/application/user-dropdown',
itemLists: ['items'],
buttonClass: 'btn btn-default btn-naked btn-rounded btn-user',
menuClass: 'pull-right',
label: Ember.computed.alias('user.username'),
populateItems: function(items) {
var self = this;
this.addActionItem(items, 'logout', 'Log Out', 'sign-out', null, function() {
self.get('parentController').send('invalidateSession');
});
}
})

View File

@ -0,0 +1,9 @@
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
toggleDrawer: function() {
this.toggleProperty('drawerShowing');
}
}
});

View File

@ -6,7 +6,11 @@ var Router = Ember.Router.extend({
});
Router.map(function() {
// this.resource('index', {path: '/'}
this.resource('dashboard', {path: '/'});
this.resource('basics');
this.resource('permissions');
this.resource('appearance');
this.resource('extensions');
});
export default Router;

View File

@ -0,0 +1 @@
Appearance

View File

@ -1 +1,43 @@
hey there
<div id="page" class="global-page with-pane">
{{application/back-button className="back-control" toggleDrawer="toggleDrawer" goBack="goBack" canGoBack=false}}
<div id="drawer" class="global-drawer">
<header id="header" class="global-header">
{{application/back-button goBack="goBack" canGoBack=true}}
<div class="container">
<div class="header-primary">
<h1 class="header-title">
Administration
</h1>
{{ui/item-list items=view.headerPrimary class="header-controls"}}
</div>
<div class="header-secondary">
{{ui/item-list items=view.headerSecondary class="header-controls"}}
</div>
</div>
</header>
</div>
<main id="content" class="global-content">
<div class="container">
<div class="side-nav admin-nav title-control">
{{ui/dropdown-select items=view.adminNav}}
</div>
<div class="admin-content">
{{outlet}}
</div>
</div>
</main>
</div>
<div id="modal" class="modal fade">
{{outlet "modal"}}
</div>
{{render "alerts"}}

View File

@ -0,0 +1 @@
Basics

View File

@ -0,0 +1 @@
Dashboard

View File

@ -1,13 +0,0 @@
<header class="hero error-hero">
<div class="container">
<h2>Error</h2>
</div>
</header>
<div class="error-area">
<div class="container">
<p>{{model.message}}</p>
<pre>{{model.stack}}</pre>
</div>
</div>

View File

@ -0,0 +1 @@
Extensions

View File

@ -0,0 +1 @@
Permissions

View File

@ -0,0 +1,79 @@
import Ember from 'ember';
import HasItemLists from '../mixins/has-item-lists';
import AdminNavItem from '../components/ui/admin-nav-item';
import SearchInput from '../components/ui/search-input';
import UserDropdown from '../components/user-dropdown';
export default Ember.View.extend(HasItemLists, {
itemLists: ['headerPrimary', 'headerSecondary', 'adminNav'],
drawerShowingChanged: Ember.observer('controller.drawerShowing', function() {
Ember.run.scheduleOnce('afterRender', this, function() {
$('body').toggleClass('drawer-open', this.get('controller.drawerShowing'));
});
}),
didInsertElement: function() {
this.$('.global-content').click(function(e) {
if (view.get('controller.drawerShowing')) {
e.preventDefault();
view.set('controller.drawerShowing', false);
}
});
},
populateHeaderSecondary: function(items) {
var controller = this.get('controller');
items.pushObjectWithTag(SearchInput.extend({
placeholder: 'Search Forum',
controller: controller,
valueBinding: Ember.Binding.oneWay('controller.searchQuery'),
activeBinding: Ember.Binding.oneWay('controller.searchActive'),
action: function(value) { controller.send('search', value); }
}), 'search');
items.pushObjectWithTag(UserDropdown.extend({
user: this.get('controller.session.user'),
parentController: controller
}), 'user');
},
populateAdminNav: function(items) {
items.pushObjectWithTag(AdminNavItem.extend({
routeName: 'dashboard',
icon: 'bar-chart',
label: 'Dashboard',
description: 'Your forum at a glance.'
}), 'dashboard');
items.pushObjectWithTag(AdminNavItem.extend({
routeName: 'basics',
icon: 'pencil',
label: 'Basics',
description: 'Set your forum title, language, and other basic settings.'
}), 'basics');
items.pushObjectWithTag(AdminNavItem.extend({
routeName: 'permissions',
icon: 'key',
label: 'Permissions',
description: 'Configure who can see and do what.'
}), 'permissions');
items.pushObjectWithTag(AdminNavItem.extend({
routeName: 'appearance',
icon: 'paint-brush',
label: 'Appearance',
description: 'Customize your forum\'s colors, logos, and other variables.'
}), 'appearance');
items.pushObjectWithTag(AdminNavItem.extend({
routeName: 'extensions',
icon: 'puzzle-piece',
label: 'Extensions',
description: 'Add extra functionality to your forum and make it your own.'
}), 'extensions');
}
});

View File

@ -3,7 +3,6 @@ export default {
initialize: function(container, application) {
application.inject('adapter', 'alerts', 'controller:alerts')
application.inject('component', 'alerts', 'controller:alerts')
application.inject('component', 'composer', 'controller:composer')
application.inject('model', 'session', 'simple-auth-session:main')
application.inject('component', 'session', 'simple-auth-session:main')
application.inject('component', 'store', 'store:main')

View File

@ -0,0 +1,6 @@
export default {
name: 'inject-composer',
initialize: function(container, application) {
application.inject('component', 'composer', 'controller:composer')
}
};

View File

@ -1,7 +0,0 @@
<div class="alerts">
{{#each alert in alerts}}
<div class="alert-wrapper">
{{view alert dismiss="dismissAlert"}}
</div>
{{/each}}
</div>

View File

@ -21,3 +21,6 @@
@import "@{common-path}/alerts.less";
@import "@{common-path}/modals.less";
@import "@{common-path}/layout.less";
@import "@{common-path}/side-nav.less";
@import "layout.less";

View File

@ -0,0 +1,76 @@
@admin-pane-width: 300px;
.admin-nav {
& .description {
display: none;
}
}
.admin-content {
padding: 20px 0;
}
@media @desktop, @desktop-hd {
.admin-nav {
position: fixed;
top: @header-height;
bottom: 0;
width: @admin-pane-width;
box-shadow: 0 2px 6px @fl-shadow-color;
background: @fl-body-bg;
border-top: 1px solid @fl-body-control-bg;
& .dropdown-select .dropdown-menu > li {
& > a {
padding: 15px 15px 15px 45px;
display: block;
text-decoration: none;
white-space: normal;
}
& > a, & > a:hover, &.active > a {
color: @fl-body-muted-color;
}
&.active > a {
background: @fl-body-secondary-color;
font-weight: normal;
& .label, & .icon {
color: @fl-body-color;
}
& .label {
font-weight: bold;
}
}
&:hover:not(.active) {
& .label {
text-decoration: underline;
}
}
}
& .icon {
float: left;
margin-left: -30px;
font-size: 14px;
margin-top: 2px;
}
& .label {
display: block;
font-size: 15px;
font-weight: normal;
margin: 0 0 5px;
}
& .description {
display: block;
font-size: 12px;
}
}
.admin-content {
margin-left: @admin-pane-width;
padding: 20px;
}
.container {
width: 100%;
.global-content & {
padding: 0;
}
}
}