mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Work in Progress: Content Editing in Admin Section
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
This controller is used for editing site content
|
||||
|
||||
@class AdminSiteContentEditController
|
||||
@extends Ember.ObjectController
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminSiteContentEditController = Discourse.ObjectController.extend({
|
||||
|
||||
saveDisabled: function() {
|
||||
if (this.get('saving')) return true;
|
||||
if (this.blank('content.content')) return true;
|
||||
return false;
|
||||
}.property('saving', 'content.content'),
|
||||
|
||||
saveChanges: function() {
|
||||
var controller = this;
|
||||
controller.setProperties({saving: true, saved: false});
|
||||
this.get('content').save().then(function () {
|
||||
controller.setProperties({saving: false, saved: true});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
39
app/assets/javascripts/admin/models/site_content.js
Normal file
39
app/assets/javascripts/admin/models/site_content.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
Our data model for interacting with custom site content
|
||||
|
||||
@class SiteContent
|
||||
@extends Discourse.Model
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.SiteContent = Discourse.Model.extend({
|
||||
|
||||
markdown: Ember.computed.equal('format', 'markdown'),
|
||||
plainText: Ember.computed.equal('format', 'plain'),
|
||||
html: Ember.computed.equal('format', 'html'),
|
||||
css: Ember.computed.equal('format', 'css'),
|
||||
|
||||
/**
|
||||
Save the content
|
||||
|
||||
@method save
|
||||
@return {jqXHR} a jQuery Promise object
|
||||
**/
|
||||
save: function() {
|
||||
return Discourse.ajax(Discourse.getURL("/admin/site_contents/" + this.get('content_type')), {
|
||||
type: 'PUT',
|
||||
data: {content: this.get('content')}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Discourse.SiteContent.reopenClass({
|
||||
|
||||
find: function(type) {
|
||||
return Discourse.ajax(Discourse.getURL("/admin/site_contents/" + type)).then(function (data) {
|
||||
return Discourse.SiteContent.create(data.site_content);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
21
app/assets/javascripts/admin/models/site_content_type.js
Normal file
21
app/assets/javascripts/admin/models/site_content_type.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
Our data model that represents types of editing site content
|
||||
|
||||
@class SiteContentType
|
||||
@extends Discourse.Model
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.SiteContentType = Discourse.Model.extend({});
|
||||
|
||||
Discourse.SiteContentType.reopenClass({
|
||||
findAll: function() {
|
||||
var contentTypes = Em.A();
|
||||
Discourse.ajax(Discourse.getURL("/admin/site_content_types")).then(function(data) {
|
||||
data.forEach(function (ct) {
|
||||
contentTypes.pushObject(Discourse.SiteContentType.create(ct));
|
||||
});
|
||||
});
|
||||
return contentTypes;
|
||||
}
|
||||
});
|
||||
@@ -14,19 +14,17 @@ Discourse.SiteCustomization = Discourse.Model.extend({
|
||||
return this.startTrackingChanges();
|
||||
},
|
||||
|
||||
description: (function() {
|
||||
description: function() {
|
||||
return "" + this.name + (this.enabled ? ' (*)' : '');
|
||||
}).property('selected', 'name'),
|
||||
}.property('selected', 'name'),
|
||||
|
||||
changed: (function() {
|
||||
changed: function() {
|
||||
var _this = this;
|
||||
if (!this.originals) {
|
||||
return false;
|
||||
}
|
||||
if (!this.originals) return false;
|
||||
return this.trackedProperties.any(function(p) {
|
||||
return _this.originals[p] !== _this.get(p);
|
||||
});
|
||||
}).property('override_default_style', 'enabled', 'name', 'stylesheet', 'header', 'originals'),
|
||||
}.property('override_default_style', 'enabled', 'name', 'stylesheet', 'header', 'originals'),
|
||||
|
||||
startTrackingChanges: function() {
|
||||
var _this = this;
|
||||
@@ -37,18 +35,17 @@ Discourse.SiteCustomization = Discourse.Model.extend({
|
||||
});
|
||||
},
|
||||
|
||||
previewUrl: (function() {
|
||||
previewUrl: function() {
|
||||
return "/?preview-style=" + (this.get('key'));
|
||||
}).property('key'),
|
||||
}.property('key'),
|
||||
|
||||
disableSave: (function() {
|
||||
disableSave: function() {
|
||||
return !this.get('changed');
|
||||
}).property('changed'),
|
||||
}.property('changed'),
|
||||
|
||||
save: function() {
|
||||
var data;
|
||||
this.startTrackingChanges();
|
||||
data = {
|
||||
var data = {
|
||||
name: this.name,
|
||||
enabled: this.enabled,
|
||||
stylesheet: this.stylesheet,
|
||||
@@ -66,7 +63,6 @@ Discourse.SiteCustomization = Discourse.Model.extend({
|
||||
|
||||
destroy: function() {
|
||||
if (!this.id) return;
|
||||
|
||||
return Discourse.ajax({
|
||||
url: Discourse.getURL("/admin/site_customizations/") + this.id,
|
||||
type: 'DELETE'
|
||||
@@ -76,13 +72,12 @@ Discourse.SiteCustomization = Discourse.Model.extend({
|
||||
});
|
||||
|
||||
var SiteCustomizations = Ember.ArrayProxy.extend({
|
||||
selectedItemChanged: (function() {
|
||||
var selected;
|
||||
selected = this.get('selectedItem');
|
||||
selectedItemChanged: function() {
|
||||
var selected = this.get('selectedItem');
|
||||
return this.get('content').each(function(i) {
|
||||
return i.set('selected', selected === i);
|
||||
});
|
||||
}).observes('selectedItem')
|
||||
}.observes('selectedItem')
|
||||
});
|
||||
|
||||
Discourse.SiteCustomization.reopenClass({
|
||||
|
||||
@@ -8,6 +8,12 @@ Discourse.Route.buildRoutes(function() {
|
||||
this.resource('admin', { path: '/admin' }, function() {
|
||||
this.route('dashboard', { path: '/' });
|
||||
this.route('site_settings', { path: '/site_settings' });
|
||||
|
||||
|
||||
this.resource('adminSiteContents', { path: '/site_contents' }, function() {
|
||||
this.resource('adminSiteContentEdit', {path: '/:content_type'});
|
||||
});
|
||||
|
||||
this.route('email_logs', { path: '/email_logs' });
|
||||
this.route('customize', { path: '/customize' });
|
||||
this.route('api', {path: '/api'});
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
Allows users to customize site content
|
||||
|
||||
@class AdminSiteContentEditRoute
|
||||
@extends Discourse.Route
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminSiteContentEditRoute = Discourse.Route.extend({
|
||||
|
||||
serialize: function(model) {
|
||||
return {content_type: model.get('content_type')};
|
||||
},
|
||||
|
||||
model: function(params) {
|
||||
return {content_type: params.content_type};
|
||||
},
|
||||
|
||||
renderTemplate: function() {
|
||||
this.render('admin/templates/site_content_edit', {into: 'admin/templates/site_contents'});
|
||||
},
|
||||
|
||||
exit: function() {
|
||||
this._super();
|
||||
this.render('admin/templates/site_contents_empty', {into: 'admin/templates/site_contents'});
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
controller.set('loaded', false);
|
||||
controller.setProperties({saving: false, saved: false});
|
||||
|
||||
Discourse.SiteContent.find(Em.get(model, 'content_type')).then(function (sc) {
|
||||
controller.set('content', sc);
|
||||
controller.set('loaded', true);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
Allows users to customize site content
|
||||
|
||||
@class AdminSiteContentsRoute
|
||||
@extends Discourse.Route
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminSiteContentsRoute = Discourse.Route.extend({
|
||||
|
||||
model: function() {
|
||||
return Discourse.SiteContentType.findAll();
|
||||
},
|
||||
|
||||
renderTemplate: function() {
|
||||
this.render('admin/templates/site_contents', {into: 'admin/templates/admin'});
|
||||
this.render('admin/templates/site_contents_empty', {into: 'admin/templates/site_contents'});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="full-width">
|
||||
|
||||
<div class="full-width">
|
||||
|
||||
<ul class="nav nav-pills">
|
||||
<li>{{#linkTo 'admin.dashboard'}}{{i18n admin.dashboard.title}}{{/linkTo}}</li>
|
||||
<li>{{#linkTo 'admin.site_settings'}}{{i18n admin.site_settings.title}}{{/linkTo}}</li>
|
||||
<li>{{#linkTo 'adminSiteContents'}}{{i18n admin.site_content.title}}{{/linkTo}}</li>
|
||||
<li>{{#linkTo 'adminUsersList.active'}}{{i18n admin.users.title}}{{/linkTo}}</li>
|
||||
<li>{{#linkTo 'admin.email_logs'}}{{i18n admin.email_logs.title}}{{/linkTo}}</li>
|
||||
<li>{{#linkTo 'adminFlags.active'}}{{i18n admin.flags.title}}{{/linkTo}}</li>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
{{#if loaded}}
|
||||
<h3>{{title}}</h3>
|
||||
<p class='description'>{{description}}</p>
|
||||
|
||||
{{#if markdown}}
|
||||
{{view Discourse.PagedownEditor valueBinding="content.content"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if plainText}}
|
||||
{{view Ember.TextArea valueBinding="content.content" class="plain"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if html}}
|
||||
{{view Discourse.AceEditorView contentBinding="content.content" mode="html"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if css}}
|
||||
{{view Discourse.AceEditorView contentBinding="content.content" mode="css"}}
|
||||
{{/if}}
|
||||
|
||||
|
||||
|
||||
<div class='controls'>
|
||||
<button class='btn' {{action saveChanges}} {{bindAttr disabled="saveDisabled"}}>
|
||||
{{#if saving}}
|
||||
{{i18n saving}}
|
||||
{{else}}
|
||||
{{i18n save}}
|
||||
{{/if}}
|
||||
</button>
|
||||
{{#if saved}}{{i18n saved}}{{/if}}
|
||||
</div>
|
||||
|
||||
{{else}}
|
||||
<div class='spinner'>{{i18n loading}}</div>
|
||||
{{/if}}
|
||||
@@ -0,0 +1,16 @@
|
||||
<div class='row'>
|
||||
<div class='content-list span6'>
|
||||
<h3>{{i18n admin.site_content.edit}}</h3>
|
||||
<ul>
|
||||
{{#each type in content}}
|
||||
<li>
|
||||
{{#linkTo 'adminSiteContentEdit' type}}{{type.title}}{{/linkTo}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class='content-editor span15'>
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
<p>{{i18n admin.site_content.none}}</p>
|
||||
@@ -36,6 +36,7 @@ Discourse.AceEditorView = Discourse.View.extend({
|
||||
didInsertElement: function() {
|
||||
var initAce,
|
||||
_this = this;
|
||||
|
||||
initAce = function() {
|
||||
_this.editor = ace.edit(_this.$('.ace')[0]);
|
||||
_this.editor.setTheme("ace/theme/chrome");
|
||||
|
||||
Reference in New Issue
Block a user