Tags management api hookup

Ref #4248
- Added tags settings menu
- Added basic new, edit, delete, and save actions
- Show actionable edit buttons dynamically based on tag state
- Infinite scroll
- Closing the tag settings menu rollbacks your changes
- Removed not-yet-implementable code
This commit is contained in:
Matt Enlow 2014-11-19 17:27:45 -07:00
parent 0c38a839b0
commit bd0f5e0c5b
9 changed files with 123 additions and 78 deletions

View File

@ -0,0 +1,50 @@
import PaginationMixin from 'ghost/mixins/pagination-controller';
var TagsController = Ember.ArrayController.extend(PaginationMixin, {
tags: Ember.computed.alias('model'),
activeTag: null,
init: function (options) {
options = options || {};
options.modelType = 'tag';
this._super(options);
},
actions: {
// Clear any unsaved changes until autosave is implemented
closeTagEditor: function () {
this.get('activeTag').rollback();
this.send('closeSettingsMenu');
},
newTag: function () {
this.set('activeTag', this.store.createRecord('tag'));
this.send('openSettingsMenu');
},
editTag: function (tag) {
this.set('activeTag', tag);
this.send('openSettingsMenu');
},
deleteTag: function (tag) {
var name = tag.get('name'),
self = this;
this.send('closeSettingsMenu');
tag.destroyRecord().then(function () {
self.notifications.showSuccess('Deleted ' + name);
}).catch(function (error) {
self.notifications.showAPIError(error);
});
},
saveTag: function (tag) {
var name = tag.get('name'),
self = this;
tag.save().then(function () {
self.notifications.showSuccess('Saved ' + name);
}).catch(function (error) {
self.notifications.showAPIError(error);
});
}
}
});
export default TagsController;

View File

@ -17,7 +17,7 @@ var PaginationControllerMixin = Ember.Mixin.create({
* } * }
*/ */
init: function (options) { init: function (options) {
this._super(); this._super(options);
var metadata = this.store.metadataFor(options.modelType); var metadata = this.store.metadataFor(options.modelType);

View File

@ -31,12 +31,15 @@ var ApplicationRoute = Ember.Route.extend(SimpleAuth.ApplicationRouteMixin, Shor
this.toggleProperty('controller.showGlobalMobileNav'); this.toggleProperty('controller.showGlobalMobileNav');
}, },
toggleSettingsMenu: function () { openSettingsMenu: function () {
this.toggleProperty('controller.showSettingsMenu'); this.set('controller.showSettingsMenu', true);
}, },
closeSettingsMenu: function () { closeSettingsMenu: function () {
this.set('controller.showSettingsMenu', false); this.set('controller.showSettingsMenu', false);
}, },
toggleSettingsMenu: function () {
this.toggleProperty('controller.showSettingsMenu');
},
closePopups: function () { closePopups: function () {
this.get('dropdown').closeDropdowns(); this.get('dropdown').closeDropdowns();

View File

@ -1,7 +1,8 @@
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 PaginationRouteMixin from 'ghost/mixins/pagination-route';
var TagsRoute = AuthenticatedRoute.extend(CurrentUserSettings, { var TagsRoute = AuthenticatedRoute.extend(CurrentUserSettings, PaginationRouteMixin, {
beforeModel: function () { beforeModel: function () {
if (!this.get('config.tagsUI')) { if (!this.get('config.tagsUI')) {
@ -14,6 +15,20 @@ var TagsRoute = AuthenticatedRoute.extend(CurrentUserSettings, {
model: function () { model: function () {
return this.store.find('tag'); return this.store.find('tag');
},
setupController: function (controller, model) {
this._super(controller, model);
this.setupPagination();
},
renderTemplate: function (controller, model) {
this._super(controller, model);
this.render('settings/tags/settings-menu', {
into: 'application',
outlet: 'settings-menu',
view: 'settings/tags/settings-menu'
});
} }
}); });

View File

@ -3,7 +3,7 @@
{{render 'post-tags-input'}} {{render 'post-tags-input'}}
<div class="publish-bar-actions"> <div class="publish-bar-actions">
<button type="button" class='post-settings' {{action "toggleSettingsMenu"}}></button> <button type="button" class="post-settings" {{action "toggleSettingsMenu"}}></button>
{{view "editor-save-button" id="entry-actions" classNameBindings="isNew:unsaved"}} {{view "editor-save-button" id="entry-actions" classNameBindings="isNew:unsaved"}}
</div> </div>
</div> </div>

View File

@ -2,84 +2,17 @@
<a class="btn btn-default btn-back active" href="/ghost/settings/">Back</a> <a class="btn btn-default btn-back active" href="/ghost/settings/">Back</a>
<h2 class="page-title">Tags</h2> <h2 class="page-title">Tags</h2>
<section class="page-actions"> <section class="page-actions">
<button type="button" class="btn btn-green">New Tag</button> <button type="button" class="btn btn-green" {{action "newTag"}}>New Tag</button>
<span class="tags-search">
<button href="#" class="btn btn-default">
<i class="icon-search"></i>
<span class="hidden">Search Tags</span>
</button>
<input type="text" class="tags-search-input">
</span>
</section> </section>
</header> </header>
<section class="content settings-tags"> <section class="content settings-tags">
{{#each}} {{#each tag in tags}}
<div class="settings-tag"> <div class="settings-tag">
<a href="#" class="tag-title">{{name}}</a> <button {{action "editTag" tag}} class="tag-title">{{tag.name}}</button>
<span class="label label-default">/{{slug}}</span> <span class="label label-default">/{{tag.slug}}</span>
<p class="tag-description">{{description}}</p> <p class="tag-description">{{tag.description}}</p>
<span class="tags-count">N/A</span> <span class="tags-count">N/A</span>
</div> </div>
{{/each}} {{/each}}
</section> </section>
{{!-- This is the example markup
<section class="content settings-tags">
<div class="settings-tag">
<a href="#" class="tag-title">News</a>
<span class="label label-default">/news</span>
<p class="tag-description">The latest news, reviews and information from around the world</p>
<span class="tags-count">20</span>
<div class="settings-tag">
<a href="#" class="tag-title">General</a>
<span class="label label-default">/news/general</span>
<p class="tag-description">My go-to category when Im not really sure what else to file news</p>
<span class="tags-count">7</span>
</div>
</div>
<div class="settings-tag">
<a href="#" class="tag-title">Image</a>
<span class="label label-alt">Private</span>
<p class="tag-description">All posts with the “image” post format</p>
<span class="tags-count">12</span>
</div>
<div class="settings-tag">
<a href="#" class="tag-title">Kittens</a>
<span class="label label-default">/kittens</span>
<p class="tag-description">My sordid past and wrongdoings</p>
<span class="tags-count">9</span>
<div class="settings-tag">
<a href="#" class="tag-title">A Short History of Nearly Everything</a>
<span class="label label-default">/kittens/a-short-history</span>
<span class="tags-count">4</span>
<div class="settings-tag">
<a href="#" class="tag-title">In Parts</a>
<span class="label label-default">/kittens/a-short-history/in-parts</span>
<p class="tag-description">Lorem ipsum kittens innit</p>
<span class="tags-count">2</span>
</div>
</div>
</div>
<div class="settings-tag">
<a href="#" class="tag-title">Video</a>
<span class="label label-default">Private</span>
<p class="tag-description">All posts containing a YouTube video link</p>
<span class="tags-count">6</span>
</div>
<div class="settings-tag">
<a href="#" class="tag-title">The End</a>
<span class="label label-default">/the-end</span>
<p class="tag-description">The final frontier</p>
<span class="tags-count">1</span>
</div>
</section>
--}}

View File

@ -0,0 +1,34 @@
<div class="content-cover" {{action "closeTagEditor"}}></div>
<div class="settings-menu-container">
<div class="settings-menu settings-menu-pane settings-menu-pane-in">
<div class="settings-menu-header">
<h4>Tag Settings</h4>
<button class="close icon-x settings-menu-header-action" {{action "closeTagEditor"}}>
<span class="hidden">Close</span>
</button>
</div>
<div class="settings-menu-content">
<form>
<div class="form-group">
<label>Tag Name</label>
{{input type="text" value=activeTag.name}}
</div>
<div class="form-group">
<label>Slug</label>{{!--@TODO show full url preview, not just slug--}}
{{input type="text" value=activeTag.slug}}
</div>
<div class="form-group">
<label>Description</label>
{{textarea value=activeTag.description}}
</div>
{{#unless activeTag.isNew}}
<button class="btn btn-red icon-trash" {{action "deleteTag" activeTag}}>Delete Tag</button>
{{/unless}}
<button class="btn btn-green tag-save-button" {{action "saveTag" activeTag}}>{{view.saveText}}</button>
</form>
</div>
</div>
</div>

View File

@ -1,5 +1,6 @@
import BaseView from 'ghost/views/settings/content-base'; import BaseView from 'ghost/views/settings/content-base';
import PaginationScrollMixin from 'ghost/mixins/pagination-view-infinite-scroll';
var SettingsTagsView = BaseView.extend(); var SettingsTagsView = BaseView.extend(PaginationScrollMixin);
export default SettingsTagsView; export default SettingsTagsView;

View File

@ -0,0 +1,9 @@
var TagsSettingsMenuView = Ember.View.extend({
saveText: Ember.computed('controller.model.isNew', function () {
return this.get('controller.model.isNew') ?
'Add Tag' :
'Save Tag';
})
});
export default TagsSettingsMenuView;