From 0932e825087bed030f3ecddb71a5e6563e8776bf Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 6 Aug 2015 12:43:56 -0400 Subject: [PATCH] Refactor Customizations to have deeper URLs --- .../admin/components/customize-link.js.es6 | 10 ++ .../controllers/admin-customize-colors.js.es6 | 9 -- .../admin-customize-css-html-show.js.es6 | 76 ++++++++++++ .../admin-customize-css-html.js.es6 | 69 ----------- .../admin/models/site-customization.js.es6 | 31 +++++ .../admin/models/site_customization.js | 116 ------------------ .../admin-customize-css-html-show.js.es6 | 11 ++ .../routes/admin-customize-css-html.js.es6 | 23 +++- .../admin/routes/admin-route-map.js.es6 | 6 +- .../templates/components/customize-link.hbs | 5 + .../templates/customize-css-html-index.hbs | 1 + .../templates/customize-css-html-show.hbs | 74 +++++++++++ .../admin/templates/customize-css-html.hbs | 13 ++ .../javascripts/admin/templates/customize.hbs | 2 +- .../admin/templates/customize_css_html.hbs | 84 ------------- .../admin/views/admin-customize.js.es6 | 18 +++ .../admin/views/admin_customize_view.js | 68 ---------- .../discourse/adapters/rest.js.es6 | 2 +- .../controllers/upload-customization.js.es6 | 31 +---- .../discourse/helpers/fa-icon.js.es6 | 3 + .../javascripts/discourse/models/store.js.es6 | 6 + .../templates/modal/upload-customization.hbs | 2 +- .../admin/site_customizations_controller.rb | 2 +- config/routes.rb | 1 + test/javascripts/models/store-test.js.es6 | 9 ++ 25 files changed, 294 insertions(+), 378 deletions(-) create mode 100644 app/assets/javascripts/admin/components/customize-link.js.es6 create mode 100644 app/assets/javascripts/admin/controllers/admin-customize-css-html-show.js.es6 delete mode 100644 app/assets/javascripts/admin/controllers/admin-customize-css-html.js.es6 create mode 100644 app/assets/javascripts/admin/models/site-customization.js.es6 delete mode 100644 app/assets/javascripts/admin/models/site_customization.js create mode 100644 app/assets/javascripts/admin/routes/admin-customize-css-html-show.js.es6 create mode 100644 app/assets/javascripts/admin/templates/components/customize-link.hbs create mode 100644 app/assets/javascripts/admin/templates/customize-css-html-index.hbs create mode 100644 app/assets/javascripts/admin/templates/customize-css-html-show.hbs create mode 100644 app/assets/javascripts/admin/templates/customize-css-html.hbs delete mode 100644 app/assets/javascripts/admin/templates/customize_css_html.hbs create mode 100644 app/assets/javascripts/admin/views/admin-customize.js.es6 delete mode 100644 app/assets/javascripts/admin/views/admin_customize_view.js diff --git a/app/assets/javascripts/admin/components/customize-link.js.es6 b/app/assets/javascripts/admin/components/customize-link.js.es6 new file mode 100644 index 00000000000..79d8cc26f4a --- /dev/null +++ b/app/assets/javascripts/admin/components/customize-link.js.es6 @@ -0,0 +1,10 @@ +export default Ember.Component.extend({ + router: function() { + return this.container.lookup('router:main'); + }.property(), + + active: function() { + const id = this.get('customization.id'); + return this.get('router.url').indexOf(`/customize/css_html/${id}/css`) !== -1; + }.property('router.url', 'customization.id') +}); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 index 636905c009a..4a6a58021bb 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 @@ -1,13 +1,4 @@ -/** - This controller supports interface for creating custom CSS skins in Discourse. - - @class AdminCustomizeColorsController - @extends Ember.Controller - @namespace Discourse - @module Discourse -**/ export default Ember.ArrayController.extend({ - onlyOverridden: false, baseColorScheme: function() { diff --git a/app/assets/javascripts/admin/controllers/admin-customize-css-html-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-css-html-show.js.es6 new file mode 100644 index 00000000000..01dc0da3259 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-customize-css-html-show.js.es6 @@ -0,0 +1,76 @@ +const sections = ['css', 'header', 'top', 'footer', 'head-tag', 'body-tag', + 'mobile-css', 'mobile-header', 'mobile-top', 'mobile-footer' ]; + +const activeSections = {}; +sections.forEach(function(s) { + activeSections[Ember.String.camelize(s) + "Active"] = Ember.computed.equal('section', s); +}); + + +export default Ember.Controller.extend(activeSections, { + maximized: false, + section: null, + + previewUrl: Discourse.computed.url("model.key", "/?preview-style=%@"), + downloadUrl: Discourse.computed.url('model.id', '/admin/size_customizations/%@'), + + mobile: function() { + return this.get('section').startsWith('mobile-'); + }.property('section'), + + maximizeIcon: function() { + return this.get('maximized') ? 'compress' : 'expand'; + }.property('maximized'), + + saveButtonText: function() { + return this.get('model.isSaving') ? I18n.t('saving') : I18n.t('admin.customize.save'); + }.property('model.isSaving'), + + saveDisabled: function() { + return !this.get('model.changed') || this.get('model.isSaving'); + }.property('model.changed', 'model.isSaving'), + + needs: ['adminCustomizeCssHtml'], + + undoPreviewUrl: Discourse.computed.url('/?preview-style='), + defaultStyleUrl: Discourse.computed.url('/?preview-style=default'), + + actions: { + save() { + this.get('model').saveChanges(); + }, + + destroy() { + const self = this; + return bootbox.confirm(I18n.t("admin.customize.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) { + if (result) { + const model = self.get('model'); + model.destroyRecord().then(function() { + self.get('controllers.adminCustomizeCssHtml').get('model').removeObject(model); + self.transitionToRoute('adminCustomizeCssHtml'); + }); + } + }); + }, + + toggleMaximize: function() { + this.toggleProperty('maximized'); + }, + + toggleMobile: function() { + const section = this.get('section'); + + // Try to send to the same tab as before + let dest; + if (this.get('mobile')) { + dest = section.replace('mobile-', ''); + if (sections.indexOf(dest) === -1) { dest = 'css'; } + } else { + dest = 'mobile-' + section; + if (sections.indexOf(dest) === -1) { dest = 'mobile-css'; } + } + this.replaceWith('adminCustomizeCssHtml.show', this.get('model.id'), dest); + } + } + +}); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-css-html.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-css-html.js.es6 deleted file mode 100644 index d71267589d4..00000000000 --- a/app/assets/javascripts/admin/controllers/admin-customize-css-html.js.es6 +++ /dev/null @@ -1,69 +0,0 @@ -import showModal from 'discourse/lib/show-modal'; - -export default Ember.ArrayController.extend({ - - undoPreviewUrl: function() { - return Discourse.getURL("/?preview-style="); - }.property(), - - defaultStyleUrl: function() { - return Discourse.getURL("/?preview-style=default"); - }.property(), - - actions: { - - /** - Create a new customization style - - @method newCustomization - **/ - newCustomization: function() { - var item = Discourse.SiteCustomization.create({name: I18n.t("admin.customize.new_style")}); - this.pushObject(item); - this.set('selectedItem', item); - }, - - importModal: function() { - showModal('upload-customization'); - }, - - /** - Select a given style - - @method selectStyle - @param {Discourse.SiteCustomization} style The style we are selecting - **/ - selectStyle: function(style) { - this.set('selectedItem', style); - }, - - /** - Save the current customization - - @method save - **/ - save: function() { - this.get('selectedItem').save(); - }, - - /** - Destroy the current customization - - @method destroy - **/ - destroy: function() { - var _this = this; - return bootbox.confirm(I18n.t("admin.customize.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) { - var selected; - if (result) { - selected = _this.get('selectedItem'); - selected.destroy(); - _this.set('selectedItem', null); - return _this.removeObject(selected); - } - }); - } - - } - -}); diff --git a/app/assets/javascripts/admin/models/site-customization.js.es6 b/app/assets/javascripts/admin/models/site-customization.js.es6 new file mode 100644 index 00000000000..655d15bf726 --- /dev/null +++ b/app/assets/javascripts/admin/models/site-customization.js.es6 @@ -0,0 +1,31 @@ +import RestModel from 'discourse/models/rest'; + +const trackedProperties = [ + 'enabled', 'name', 'stylesheet', 'header', 'top', 'footer', 'mobile_stylesheet', + 'mobile_header', 'mobile_top', 'mobile_footer', 'head_tag', 'body_tag' +]; + +function changed() { + const originals = this.get('originals'); + if (!originals) { return false; } + return _.some(trackedProperties, (p) => originals[p] !== this.get(p)); +} + +const SiteCustomization = RestModel.extend({ + description: function() { + return "" + this.name + (this.enabled ? ' (*)' : ''); + }.property('selected', 'name', 'enabled'), + + changed: changed.property.apply(changed, trackedProperties.concat('originals')), + + startTrackingChanges: function() { + this.set('originals', this.getProperties(trackedProperties)); + }.on('init'), + + saveChanges() { + return this.save(this.getProperties(trackedProperties)).then(() => this.startTrackingChanges()); + }, + +}); + +export default SiteCustomization; diff --git a/app/assets/javascripts/admin/models/site_customization.js b/app/assets/javascripts/admin/models/site_customization.js deleted file mode 100644 index 19fcbad266e..00000000000 --- a/app/assets/javascripts/admin/models/site_customization.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - Our data model for interacting with site customizations. - - @class SiteCustomization - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.SiteCustomization = Discourse.Model.extend({ - trackedProperties: [ - 'enabled', 'name', - 'stylesheet', 'header', 'top', 'footer', - 'mobile_stylesheet', 'mobile_header', 'mobile_top', 'mobile_footer', - 'head_tag', 'body_tag' - ], - - description: function() { - return "" + this.name + (this.enabled ? ' (*)' : ''); - }.property('selected', 'name', 'enabled'), - - changed: function() { - var self = this; - - if (!this.originals) { return false; } - - var changed = _.some(this.trackedProperties, function (p) { - return self.originals[p] !== self.get(p); - }); - - if (changed) { this.set('savingStatus', ''); } - - return changed; - }.property('enabled', 'name', 'originals', - 'stylesheet', 'header', 'top', 'footer', - 'mobile_stylesheet', 'mobile_header', 'mobile_top', 'mobile_footer', - 'head_tag', 'body_tag'), - - startTrackingChanges: function() { - var self = this; - var originals = {}; - _.each(this.trackedProperties, function (prop) { - originals[prop] = self.get(prop); - }); - this.set('originals', originals); - }.on('init'), - - previewUrl: function() { return Discourse.getURL("/?preview-style=" + this.get('key')); }.property('key'), - disableSave: function() { return !this.get('changed') || this.get('saving'); }.property('changed'), - - save: function() { - this.set('savingStatus', I18n.t('saving')); - this.set('saving',true); - - var data = { - name: this.name, - enabled: this.enabled, - stylesheet: this.stylesheet, - header: this.header, - top: this.top, - footer: this.footer, - mobile_stylesheet: this.mobile_stylesheet, - mobile_header: this.mobile_header, - mobile_top: this.mobile_top, - mobile_footer: this.mobile_footer, - head_tag: this.head_tag, - body_tag: this.body_tag - }; - - var siteCustomization = this; - return Discourse.ajax("/admin/site_customizations" + (this.id ? '/' + this.id : ''), { - data: { site_customization: data }, - type: this.id ? 'PUT' : 'POST' - }).then(function (result) { - if (!siteCustomization.id) { - siteCustomization.set('id', result.id); - siteCustomization.set('key', result.key); - } - siteCustomization.set('savingStatus', I18n.t('saved')); - siteCustomization.set('saving',false); - siteCustomization.startTrackingChanges(); - return siteCustomization; - }); - }, - - destroy: function() { - if (!this.id) return; - return Discourse.ajax("/admin/site_customizations/" + this.id, { type: 'DELETE' }); - }, - - download_url: function() { - return Discourse.getURL('/admin/site_customizations/' + this.id); - }.property('id') -}); - -var SiteCustomizations = Ember.ArrayProxy.extend({ - selectedItemChanged: function() { - var selected = this.get('selectedItem'); - _.each(this.get('content'), function (i) { - i.set('selected', selected === i); - }); - }.observes('selectedItem') -}); - -Discourse.SiteCustomization.reopenClass({ - findAll: function() { - return Discourse.ajax("/admin/site_customizations").then(function (data) { - var content = []; - if (data) { - content = data.site_customizations.map(function(c) { - return Discourse.SiteCustomization.create(c); - }); - } - return SiteCustomizations.create({ content: content }); - }); - } -}); diff --git a/app/assets/javascripts/admin/routes/admin-customize-css-html-show.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-css-html-show.js.es6 new file mode 100644 index 00000000000..dc38f3c51fb --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-customize-css-html-show.js.es6 @@ -0,0 +1,11 @@ +export default Ember.Route.extend({ + model(params) { + const all = this.modelFor('adminCustomizeCssHtml'); + const model = all.findProperty('id', parseInt(params.site_customization_id)); + return model ? { model, section: params.section } : this.replaceWith('adminCustomizeCssHtml.index'); + }, + + setupController(controller, hash) { + controller.setProperties(hash); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin-customize-css-html.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-css-html.js.es6 index c76c7e9a43c..8bbd22a4565 100644 --- a/app/assets/javascripts/admin/routes/admin-customize-css-html.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-customize-css-html.js.es6 @@ -1,5 +1,26 @@ +import showModal from 'discourse/lib/show-modal'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; + export default Ember.Route.extend({ model() { - return Discourse.SiteCustomization.findAll(); + return this.store.findAll('site-customization'); + }, + + actions: { + importModal() { + showModal('upload-customization'); + }, + + newCustomization(obj) { + obj = obj || {name: I18n.t("admin.customize.new_style")}; + const item = this.store.createRecord('site-customization', obj); + + const all = this.modelFor('adminCustomizeCssHtml'); + const self = this; + item.save().then(function() { + all.pushObject(item); + self.transitionTo('adminCustomizeCssHtml.show', item.get('id'), 'css'); + }).catch(popupAjaxError); + } } }); diff --git a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 index daf3b1ced6f..66d9ea4c795 100644 --- a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 @@ -16,7 +16,11 @@ export default { this.resource('adminCustomize', { path: '/customize' } ,function() { this.route('colors'); - this.route('css_html'); + + this.resource('adminCustomizeCssHtml', { path: 'css_html' }, function() { + this.route('show', {path: '/:site_customization_id/:section'}); + }); + this.resource('adminSiteText', { path: '/site_text' }, function() { this.route('edit', {path: '/:text_type'}); }); diff --git a/app/assets/javascripts/admin/templates/components/customize-link.hbs b/app/assets/javascripts/admin/templates/components/customize-link.hbs new file mode 100644 index 00000000000..dd3c4104c75 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/customize-link.hbs @@ -0,0 +1,5 @@ +
  • + + {{customization.description}} + +
  • diff --git a/app/assets/javascripts/admin/templates/customize-css-html-index.hbs b/app/assets/javascripts/admin/templates/customize-css-html-index.hbs new file mode 100644 index 00000000000..781d063c7f2 --- /dev/null +++ b/app/assets/javascripts/admin/templates/customize-css-html-index.hbs @@ -0,0 +1 @@ +

    {{i18n 'admin.customize.about'}}

    diff --git a/app/assets/javascripts/admin/templates/customize-css-html-show.hbs b/app/assets/javascripts/admin/templates/customize-css-html-show.hbs new file mode 100644 index 00000000000..4d93f5ee890 --- /dev/null +++ b/app/assets/javascripts/admin/templates/customize-css-html-show.hbs @@ -0,0 +1,74 @@ +
    +
    + {{text-field class="style-name" value=model.name}} + {{fa-icon "download"}} {{i18n 'admin.export_json.button_text'}} + +
    + +
    + +
    + {{#if cssActive}}{{ace-editor content=model.stylesheet mode="scss"}}{{/if}} + {{#if headerActive}}{{ace-editor content=model.header mode="html"}}{{/if}} + {{#if topActive}}{{ace-editor content=model.top mode="html"}}{{/if}} + {{#if footerActive}}{{ace-editor content=model.footer mode="html"}}{{/if}} + {{#if headTagActive}}{{ace-editor content=model.head_tag mode="html"}}{{/if}} + {{#if bodyTagActive}}{{ace-editor content=model.body_tag mode="html"}}{{/if}} + {{#if mobileCssActive}}{{ace-editor content=model.mobile_stylesheet mode="scss"}}{{/if}} + {{#if mobileHeaderActive}}{{ace-editor content=model.mobile_header mode="html"}}{{/if}} + {{#if mobileTopActive}}{{ace-editor content=model.mobile_top mode="html"}}{{/if}} + {{#if mobileFooterActive}}{{ace-editor content=model.mobile_footer mode="html"}}{{/if}} +
    + + +
    +
    + diff --git a/app/assets/javascripts/admin/templates/customize-css-html.hbs b/app/assets/javascripts/admin/templates/customize-css-html.hbs new file mode 100644 index 00000000000..73b8e22c9f2 --- /dev/null +++ b/app/assets/javascripts/admin/templates/customize-css-html.hbs @@ -0,0 +1,13 @@ +
    +

    {{i18n 'admin.customize.css_html.long_title'}}

    + + + {{d-button label="admin.customize.new" icon="plus" action="newCustomization" class="btn-primary"}} + {{d-button action="importModal" icon="upload" label="admin.customize.import"}} +
    + +{{outlet}} diff --git a/app/assets/javascripts/admin/templates/customize.hbs b/app/assets/javascripts/admin/templates/customize.hbs index c009909e1a7..130b75e0ac6 100644 --- a/app/assets/javascripts/admin/templates/customize.hbs +++ b/app/assets/javascripts/admin/templates/customize.hbs @@ -1,6 +1,6 @@ {{#admin-nav}} {{nav-item route='adminCustomize.colors' label='admin.customize.colors.title'}} - {{nav-item route='adminCustomize.css_html' label='admin.customize.css_html.title'}} + {{nav-item route='adminCustomizeCssHtml.index' label='admin.customize.css_html.title'}} {{nav-item route='adminSiteText' label='admin.site_text.title'}} {{nav-item route='adminUserFields' label='admin.user_fields.title'}} {{nav-item route='adminEmojis' label='admin.emoji.title'}} diff --git a/app/assets/javascripts/admin/templates/customize_css_html.hbs b/app/assets/javascripts/admin/templates/customize_css_html.hbs deleted file mode 100644 index f4dce62b091..00000000000 --- a/app/assets/javascripts/admin/templates/customize_css_html.hbs +++ /dev/null @@ -1,84 +0,0 @@ -
    -

    {{i18n 'admin.customize.css_html.long_title'}}

    - - - {{d-button action="importModal" icon="upload" label="admin.customize.import"}} -
    - -{{#if selectedItem}} -
    -
    - {{text-field class="style-name" value=selectedItem.name}} - {{fa-icon "download"}} {{i18n 'admin.export_json.button_text'}} - - - -
    - {{#if view.stylesheetActive}}{{ace-editor content=selectedItem.stylesheet mode="scss"}}{{/if}} - {{#if view.headerActive}}{{ace-editor content=selectedItem.header mode="html"}}{{/if}} - {{#if view.topActive}}{{ace-editor content=selectedItem.top mode="html"}}{{/if}} - {{#if view.footerActive}}{{ace-editor content=selectedItem.footer mode="html"}}{{/if}} - {{#if view.headTagActive}}{{ace-editor content=selectedItem.head_tag mode="html"}}{{/if}} - {{#if view.bodyTagActive}}{{ace-editor content=selectedItem.body_tag mode="html"}}{{/if}} - {{#if view.mobileStylesheetActive}}{{ace-editor content=selectedItem.mobile_stylesheet mode="scss"}}{{/if}} - {{#if view.mobileHeaderActive}}{{ace-editor content=selectedItem.mobile_header mode="html"}}{{/if}} - {{#if view.mobileTopActive}}{{ace-editor content=selectedItem.mobile_top mode="html"}}{{/if}} - {{#if view.mobileFooterActive}}{{ace-editor content=selectedItem.mobile_footer mode="html"}}{{/if}} -
    - -
    -
    -{{else}} -

    {{i18n 'admin.customize.about'}}

    -{{/if}} diff --git a/app/assets/javascripts/admin/views/admin-customize.js.es6 b/app/assets/javascripts/admin/views/admin-customize.js.es6 new file mode 100644 index 00000000000..faca47026f6 --- /dev/null +++ b/app/assets/javascripts/admin/views/admin-customize.js.es6 @@ -0,0 +1,18 @@ +/*global Mousetrap:true */ + +export default Ember.View.extend({ + classNames: ['customize'], + + _init: function() { + var controller = this.get('controller'); + Mousetrap.bindGlobal('mod+s', function() { + controller.send("save"); + return false; + }); + }.on("didInsertElement"), + + _cleanUp: function() { + Mousetrap.unbindGlobal('mod+s'); + }.on("willDestroyElement") + +}); diff --git a/app/assets/javascripts/admin/views/admin_customize_view.js b/app/assets/javascripts/admin/views/admin_customize_view.js deleted file mode 100644 index 37ecfaceb1d..00000000000 --- a/app/assets/javascripts/admin/views/admin_customize_view.js +++ /dev/null @@ -1,68 +0,0 @@ -/*global Mousetrap:true */ - -/** - A view to handle site customizations - - @class AdminCustomizeView - @extends Discourse.View - @namespace Discourse - @module Discourse -**/ -Discourse.AdminCustomizeView = Discourse.View.extend({ - templateName: 'admin/templates/customize', - classNames: ['customize'], - selected: 'stylesheet', - mobile: false, - - stylesheetActive: Em.computed.equal('selected', 'stylesheet'), - headerActive: Em.computed.equal('selected', 'header'), - topActive: Em.computed.equal('selected', 'top'), - footerActive: Em.computed.equal('selected', 'footer'), - headTagActive: Em.computed.equal('selected', 'head_tag'), - bodyTagActive: Em.computed.equal('selected', 'body_tag'), - - mobileStylesheetActive: Em.computed.equal('selected', 'mobile_stylesheet'), - mobileHeaderActive: Em.computed.equal('selected', 'mobile_header'), - mobileTopActive: Em.computed.equal('selected', 'mobile_top'), - mobileFooterActive: Em.computed.equal('selected', 'mobile_footer'), - - actions: { - toggleMobile: function() { - // auto-select best tab - var tab = this.get("selected"); - if (/_tag$/.test(tab)) { tab = "stylesheet"; } - if (this.get("mobile")) { tab = tab.replace("mobile_", ""); } - else { tab = "mobile_" + tab; } - this.set("selected", tab); - // toggle mobile - this.toggleProperty("mobile"); - }, - - select: function(tab) { - this.set('selected', tab); - }, - - toggleMaximize: function() { - this.set("maximized", !this.get("maximized")); - - Em.run.scheduleOnce('afterRender', this, function(){ - $('.ace-wrapper').each(function(){ - $(this).data("editor").resize(); - }); - }); - }, - }, - - _init: function() { - var controller = this.get('controller'); - Mousetrap.bindGlobal('mod+s', function() { - controller.send("save"); - return false; - }); - }.on("didInsertElement"), - - _cleanUp: function() { - Mousetrap.unbindGlobal('mod+s'); - }.on("willDestroyElement") - -}); diff --git a/app/assets/javascripts/discourse/adapters/rest.js.es6 b/app/assets/javascripts/discourse/adapters/rest.js.es6 index 5a64730aba1..5e427a86589 100644 --- a/app/assets/javascripts/discourse/adapters/rest.js.es6 +++ b/app/assets/javascripts/discourse/adapters/rest.js.es6 @@ -1,4 +1,4 @@ -const ADMIN_MODELS = ['plugin']; +const ADMIN_MODELS = ['plugin', 'site-customization']; export function Result(payload, responseJson) { this.payload = payload; diff --git a/app/assets/javascripts/discourse/controllers/upload-customization.js.es6 b/app/assets/javascripts/discourse/controllers/upload-customization.js.es6 index 09158f53752..72bf3aee6ee 100644 --- a/app/assets/javascripts/discourse/controllers/upload-customization.js.es6 +++ b/app/assets/javascripts/discourse/controllers/upload-customization.js.es6 @@ -2,20 +2,15 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; export default Ember.Controller.extend(ModalFunctionality, { notReady: Em.computed.not('ready'), - - needs: ['admin-customize-css-html'], - - title: "hi", + needs: ['adminCustomizeCssHtml'], ready: function() { - let parsed; try { - parsed = JSON.parse(this.get('customizationFile')); + const parsed = JSON.parse(this.get('customizationFile')); + return !!parsed["site_customization"]; } catch (e) { return false; } - - return !!parsed["site_customization"]; }.property('customizationFile'), actions: { @@ -28,24 +23,8 @@ export default Ember.Controller.extend(ModalFunctionality, { delete object.id; delete object.key; - const customization = Discourse.SiteCustomization.create(object); - - this.set('loading', true); - customization.save().then(function(customization) { - self.send('closeModal'); - self.set('loading', false); - - const parentController = self.get('controllers.admin-customize-css-html'); - parentController.pushObject(customization); - parentController.set('selectedItem', customization); - }).catch(function(xhr) { - self.set('loading', false); - if (xhr.responseJSON) { - bootbox.alert(xhr.responseJSON.errors.join("
    ")); - } else { - bootbox.alert(I18n.t('generic_error')); - } - }); + const controller = this.get('controllers.adminCustomizeCssHtml'); + controller.send('newCustomization', object); } } diff --git a/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 b/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 index e979ebab90e..456f876054f 100644 --- a/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 +++ b/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 @@ -19,6 +19,9 @@ function iconHTML(icon, params) { return html; } +Ember.Handlebars.helper('fa-icon-bound', function(value, options) { + return new Handlebars.SafeString(iconHTML(value, options)); +}); registerUnbound('fa-icon', function(icon, params) { return new Handlebars.SafeString(iconHTML(icon, params)); diff --git a/app/assets/javascripts/discourse/models/store.js.es6 b/app/assets/javascripts/discourse/models/store.js.es6 index cda112cefb6..a9aa86f294e 100644 --- a/app/assets/javascripts/discourse/models/store.js.es6 +++ b/app/assets/javascripts/discourse/models/store.js.es6 @@ -116,6 +116,12 @@ export default Ember.Object.extend({ }, destroyRecord(type, record) { + // If the record is new, don't perform an Ajax call + if (record.get('isNew')) { + removeMap(type, record.get('id')); + return Ember.RSVP.Promise.resolve(true); + } + return this.adapterFor(type).destroyRecord(this, type, record).then(function(result) { removeMap(type, record.get('id')); return result; diff --git a/app/assets/javascripts/discourse/templates/modal/upload-customization.hbs b/app/assets/javascripts/discourse/templates/modal/upload-customization.hbs index 6d5d53e5bbf..db8cf3de279 100644 --- a/app/assets/javascripts/discourse/templates/modal/upload-customization.hbs +++ b/app/assets/javascripts/discourse/templates/modal/upload-customization.hbs @@ -1,4 +1,4 @@ -
    + diff --git a/app/controllers/admin/site_customizations_controller.rb b/app/controllers/admin/site_customizations_controller.rb index 30929fe4e09..0308b85b96b 100644 --- a/app/controllers/admin/site_customizations_controller.rb +++ b/app/controllers/admin/site_customizations_controller.rb @@ -32,7 +32,7 @@ class Admin::SiteCustomizationsController < Admin::AdminController respond_to do |format| if @site_customization.update_attributes(site_customization_params) - format.json { head :no_content } + format.json { render json: @site_customization, status: :created} else log_record.destroy if log_record format.json { render json: @site_customization.errors, status: :unprocessable_entity } diff --git a/config/routes.rb b/config/routes.rb index 98fc8396234..30f7aa34c38 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -132,6 +132,7 @@ Discourse::Application.routes.draw do get "customize" => "color_schemes#index", constraints: AdminConstraint.new get "customize/css_html" => "site_customizations#index", constraints: AdminConstraint.new + get "customize/css_html/:id/:section" => "site_customizations#index", constraints: AdminConstraint.new get "customize/colors" => "color_schemes#index", constraints: AdminConstraint.new get "customize/permalinks" => "permalinks#index", constraints: AdminConstraint.new get "flags" => "flags#index" diff --git a/test/javascripts/models/store-test.js.es6 b/test/javascripts/models/store-test.js.es6 index bac22ecd5a6..46585ce6820 100644 --- a/test/javascripts/models/store-test.js.es6 +++ b/test/javascripts/models/store-test.js.es6 @@ -97,6 +97,15 @@ test('destroyRecord', function(assert) { }); }); +test('destroyRecord when new', function(assert) { + const store = createStore(); + const w = store.createRecord('widget', {name: 'hello'}); + store.destroyRecord('widget', w).then(function(result) { + assert.ok(result); + }); +}); + + test('find embedded', function() { const store = createStore(); return store.find('fruit', 1).then(function(f) {