mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Merge pull request #4858 from PaulAdamDavis/nav-drag-order
Drag & Drop Navigation Reordering
This commit is contained in:
commit
920c80e908
8 changed files with 89 additions and 10 deletions
|
@ -394,18 +394,33 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
|
position: relative;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
@media (min-width: 601px) {
|
@media (min-width: 601px) {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// &.last-navigation-item {
|
||||||
|
&:last-child {
|
||||||
|
padding-left: 27px; // .navigation-item-drag-handle width + horizontal padding
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation-item-drag-handle {
|
.navigation-item-drag-handle {
|
||||||
padding-left: 10px;
|
padding: 6px 17px 0 10px;
|
||||||
padding-right: 17px;
|
|
||||||
width: 27px;
|
width: 27px;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
&:before {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 4px;
|
||||||
|
margin-top: -9px;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation-inputs {
|
.navigation-inputs {
|
||||||
|
@ -449,6 +464,7 @@
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
|
|
|
@ -187,6 +187,7 @@ select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid #E0DFD7;
|
border: 1px solid #E0DFD7;
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
var NavItemComponent = Ember.Component.extend({
|
var NavItemComponent = Ember.Component.extend({
|
||||||
classNames: 'navigation-item',
|
classNames: 'navigation-item',
|
||||||
|
|
||||||
|
attributeBindings: ['order:data-order'],
|
||||||
|
order: Ember.computed.readOnly('navItem.order'),
|
||||||
|
|
||||||
keyPress: function (event) {
|
keyPress: function (event) {
|
||||||
// enter key
|
// enter key
|
||||||
if (event.keyCode === 13) {
|
if (event.keyCode === 13) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ var NavigationController,
|
||||||
NavItem = Ember.Object.extend({
|
NavItem = Ember.Object.extend({
|
||||||
label: '',
|
label: '',
|
||||||
url: '',
|
url: '',
|
||||||
|
order: '',
|
||||||
|
|
||||||
isComplete: Ember.computed('label', 'url', function () {
|
isComplete: Ember.computed('label', 'url', function () {
|
||||||
return !(Ember.isBlank(this.get('label')) || Ember.isBlank(this.get('url')));
|
return !(Ember.isBlank(this.get('label')) || Ember.isBlank(this.get('url')));
|
||||||
|
@ -31,6 +32,8 @@ NavigationController = Ember.Controller.extend({
|
||||||
return NavItem.create(item);
|
return NavItem.create(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
navItems.sortBy('order');
|
||||||
|
|
||||||
lastItem = navItems.get('lastObject');
|
lastItem = navItems.get('lastObject');
|
||||||
if (!lastItem || lastItem.get('isComplete')) {
|
if (!lastItem || lastItem.get('isComplete')) {
|
||||||
navItems.addObject(NavItem.create());
|
navItems.addObject(NavItem.create());
|
||||||
|
@ -51,13 +54,24 @@ NavigationController = Ember.Controller.extend({
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
updateOrder: function (indexes) {
|
||||||
|
var navItems = this.get('navigationItems'),
|
||||||
|
order = 0;
|
||||||
|
|
||||||
|
indexes.forEach(function (index) {
|
||||||
|
navItems[index].set('order', order);
|
||||||
|
order = order + 1; // Increment order order by one
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
addItem: function () {
|
addItem: function () {
|
||||||
var navItems = this.get('navigationItems'),
|
var navItems = this.get('navigationItems'),
|
||||||
lastItem = navItems.get('lastObject');
|
lastItem = navItems.get('lastObject');
|
||||||
|
|
||||||
if (lastItem && lastItem.get('isComplete')) {
|
if (lastItem && lastItem.get('isComplete')) {
|
||||||
navItems.addObject(NavItem.create());
|
lastItem.set('order', (navItems.length - 1)); // -1 because order is 0-index, length is 1-index
|
||||||
|
navItems.addObject(NavItem.create()); // Adds new blank navItem
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -67,6 +81,14 @@ NavigationController = Ember.Controller.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.get('navigationItems').removeObject(item);
|
this.get('navigationItems').removeObject(item);
|
||||||
|
|
||||||
|
var navItems = this.get('navigationItems'),
|
||||||
|
order = 0;
|
||||||
|
|
||||||
|
navItems.forEach(function (item) {
|
||||||
|
item.set('order', order);
|
||||||
|
order = order + 1; // Increment order order by one
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
updateUrl: function (url, navItem) {
|
updateUrl: function (url, navItem) {
|
||||||
|
@ -92,7 +114,8 @@ NavigationController = Ember.Controller.extend({
|
||||||
|
|
||||||
navSetting = this.get('navigationItems').map(function (item) {
|
navSetting = this.get('navigationItems').map(function (item) {
|
||||||
var label,
|
var label,
|
||||||
url;
|
url,
|
||||||
|
order;
|
||||||
|
|
||||||
if (!item || !item.get('isComplete')) {
|
if (!item || !item.get('isComplete')) {
|
||||||
return;
|
return;
|
||||||
|
@ -100,6 +123,7 @@ NavigationController = Ember.Controller.extend({
|
||||||
|
|
||||||
label = item.get('label').trim();
|
label = item.get('label').trim();
|
||||||
url = item.get('url').trim();
|
url = item.get('url').trim();
|
||||||
|
order = item.get('order');
|
||||||
|
|
||||||
match = url.match(blogUrlRegex);
|
match = url.match(blogUrlRegex);
|
||||||
|
|
||||||
|
@ -118,9 +142,14 @@ NavigationController = Ember.Controller.extend({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {label: label, url: url};
|
return {label: label, url: url, order: order};
|
||||||
}).compact();
|
}).compact();
|
||||||
|
|
||||||
|
// Sort JSON so nav items are stored in the correct order order
|
||||||
|
navSetting.sort(function (a, b) {
|
||||||
|
return a.order - b.order;
|
||||||
|
});
|
||||||
|
|
||||||
this.set('model.navigation', JSON.stringify(navSetting));
|
this.set('model.navigation', JSON.stringify(navSetting));
|
||||||
|
|
||||||
// trigger change event because even if the final JSON is unchanged
|
// trigger change event because even if the final JSON is unchanged
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import AuthenticatedRoute from 'ghost/routes/authenticated';
|
import AuthenticatedRoute from 'ghost/routes/authenticated';
|
||||||
import CurrentUserSettings from 'ghost/mixins/current-user-settings';
|
import CurrentUserSettings from 'ghost/mixins/current-user-settings';
|
||||||
|
import styleBody from 'ghost/mixins/style-body';
|
||||||
|
|
||||||
var NavigationRoute = AuthenticatedRoute.extend(CurrentUserSettings, {
|
var NavigationRoute = AuthenticatedRoute.extend(styleBody, CurrentUserSettings, {
|
||||||
|
|
||||||
titleToken: 'Navigation',
|
titleToken: 'Navigation',
|
||||||
|
|
||||||
|
classNames: ['settings-view-navigation'],
|
||||||
|
|
||||||
beforeModel: function () {
|
beforeModel: function () {
|
||||||
if (!this.get('config.navigationUI')) {
|
if (!this.get('config.navigationUI')) {
|
||||||
return this.transitionTo('settings.general');
|
return this.transitionTo('settings.general');
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<button type="button" class="navigation-item-drag-handle icon-grab">
|
{{#unless navItem.last}}
|
||||||
|
<span class="navigation-item-drag-handle icon-grab">
|
||||||
<span class="hidden">Reorder</span>
|
<span class="hidden">Reorder</span>
|
||||||
</button>
|
</span>
|
||||||
|
{{/unless}}
|
||||||
<div class="navigation-inputs">
|
<div class="navigation-inputs">
|
||||||
<span class="navigation-item-label">
|
<span class="navigation-item-label">
|
||||||
{{gh-trim-focus-input focus=navItem.last placeholder="Label" value=navItem.label}}
|
{{gh-trim-focus-input focus=navItem.last placeholder="Label" value=navItem.label}}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section class="content settings-navigation">
|
<section class="content settings-navigation">
|
||||||
<form id="settings-navigation" novalidate="novalidate">
|
<form id="settings-navigation" class="js-settings-navigation" novalidate="novalidate">
|
||||||
{{#each navItem in navigationItems}}
|
{{#each navItem in navigationItems}}
|
||||||
{{gh-navitem navItem=navItem baseUrl=blogUrl addItem="addItem" deleteItem="deleteItem" updateUrl="updateUrl"}}
|
{{gh-navitem navItem=navItem baseUrl=blogUrl addItem="addItem" deleteItem="deleteItem" updateUrl="updateUrl"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
@ -1,6 +1,31 @@
|
||||||
import BaseView from 'ghost/views/settings/content-base';
|
import BaseView from 'ghost/views/settings/content-base';
|
||||||
|
|
||||||
var SettingsNavigationView = BaseView.extend({
|
var SettingsNavigationView = BaseView.extend({
|
||||||
|
|
||||||
|
didInsertElement: function () {
|
||||||
|
var controller = this.get('controller'),
|
||||||
|
navContainer = Ember.$('.js-settings-navigation'),
|
||||||
|
navElements = '.navigation-item:not(.navigation-item:last-child)';
|
||||||
|
|
||||||
|
navContainer.sortable({
|
||||||
|
handle: '.navigation-item-drag-handle',
|
||||||
|
items: navElements,
|
||||||
|
|
||||||
|
update: function () {
|
||||||
|
var indexes = [];
|
||||||
|
navContainer.find(navElements).each(function () {
|
||||||
|
var order = Ember.$(this).data('order');
|
||||||
|
indexes.push(order);
|
||||||
|
});
|
||||||
|
controller.updateOrder(indexes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement: function () {
|
||||||
|
Ember.$('.js-settings-navigation').sortable('destroy');
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default SettingsNavigationView;
|
export default SettingsNavigationView;
|
||||||
|
|
Loading…
Add table
Reference in a new issue