Implements Initial lifecycle and App UI start

Closes #2083

* Added hbs template for apps listing
* Added settings to read the activeApps
* Added viewcontrol to activate / deactivate apps
* Added API handler to store activeApps (by `name` in the `package.json` file)
* On button click it turns the button into "Working" and changes class to `button` (grey one)
* On success, rerenders the pane, adds success notification about apps being saved
* On error, rerenders the pane, adds error notification with error message

Missing:
* tests: couldn't figure out how to add mock apps with mock package.json data
* actually registering, etc, re #2140
* icon from the sidebar
This commit is contained in:
Gabor Javorszky 2014-02-23 12:32:35 +00:00 committed by Hannah Wolfe
parent 0575ed5a3c
commit 8b00f94c9d
4 changed files with 83 additions and 1 deletions

View File

@ -3,7 +3,7 @@
'use strict';
//id:0 is used to issue PUT requests
Ghost.Models.Settings = Ghost.ProgressModel.extend({
url: Ghost.paths.apiRoot + '/settings/?type=blog,theme',
url: Ghost.paths.apiRoot + '/settings/?type=blog,theme,app',
id: '0'
});

View File

@ -0,0 +1,15 @@
<header>
<button class="button-back">Back</button>
<h2 class="title">Apps</h2>
</header>
<section class="content">
<ul class="js-apps">
{{#each availableApps}}
<li>
{{#if package}}{{package.name}} - {{package.version}}{{else}}{{name}} - package.json missing :({{/if}}
<button data-app="{{name}}" class="{{#if active}}button-delete js-button-deactivate js-button-active">Deactivate{{else}}button-add js-button-activate">Activate{{/if}}</button>
</li>
{{/each}}
</ul>
</section>

View File

@ -5,5 +5,6 @@
<ul>
<li class="general"><a href="#general">General</a></li>
<li class="users"><a href="#user">User</a></li>
<li class="apps"><a href="#apps">Apps</a></li>
</ul>
</nav>

View File

@ -446,4 +446,70 @@
}
});
// ### Apps page
Settings.apps = Settings.Pane.extend({
id: "apps",
events: {
'click .js-button-activate': 'activateApp',
'click .js-button-deactivate': 'deactivateApp'
},
beforeRender: function () {
this.availableApps = this.model.toJSON().availableApps;
},
activateApp: function (event) {
var button = $(event.currentTarget);
button.removeClass('button-add').addClass('button js-button-active').text('Working');
this.saveStates();
},
deactivateApp: function (event) {
var button = $(event.currentTarget);
button.removeClass('button-delete js-button-active').addClass('button').text('Working');
this.saveStates();
},
saveStates: function () {
var activeButtons = this.$el.find('.js-apps .js-button-active'),
toSave = [],
self = this;
_.each(activeButtons, function (app) {
toSave.push($(app).data('app'));
});
this.model.save({
activeApps: JSON.stringify(toSave)
}, {
success: this.saveSuccess,
error: this.saveError
}).then(function () { self.render(); });
},
saveSuccess: function () {
Ghost.notifications.addItem({
type: 'success',
message: 'Active applications updated.',
status: 'passive',
id: 'success-1100'
});
},
saveError: function (xhr) {
Ghost.notifications.addItem({
type: 'error',
message: Ghost.Views.Utils.getRequestErrorMessage(xhr),
status: 'passive'
});
},
templateName: 'settings/apps'
});
}());