diff --git a/.jshintignore b/.eslintignore similarity index 96% rename from .jshintignore rename to .eslintignore index ac11baa97e..1ecda00738 100644 --- a/.jshintignore +++ b/.eslintignore @@ -20,5 +20,5 @@ vendor/ test/javascripts/helpers/ test/javascripts/test_helper.js test/javascripts/test_helper.js +test/javascripts/fixtures app/assets/javascripts/ember-addons/ - diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..149d842488 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,105 @@ +{ + "env": { + "jasmine": true, + "node": true, + "mocha": true, + "browser": true, + "builtin": true + }, + ecmaVersion: 7, + "globals": + {"Ember":true, + "jQuery":true, + "$":true, + "RSVP":true, + "Discourse":true, + "Em":true, + "PreloadStore":true, + "Handlebars":true, + "I18n":true, + "bootbox":true, + "module":true, + "moduleFor":true, + "moduleForComponent":true, + "Pretender":true, + "sandbox":true, + "controllerFor":true, + "test":true, + "ok":true, + "not":true, + "expect":true, + "equal":true, + "visit":true, + "andThen":true, + "click":true, + "currentPath":true, + "currentRouteName":true, + "currentURL":true, + "fillIn":true, + "keyEvent":true, + "triggerEvent":true, + "count":true, + "exists":true, + "visible":true, + "invisible":true, + "asyncRender":true, + "selectDropdown":true, + "asyncTestDiscourse":true, + "fixture":true, + "find":true, + "sinon":true, + "moment":true, + "start":true, + "_":true, + "alert":true, + "containsInstance":true, + "deepEqual":true, + "notEqual":true, + "define":true, + "require":true, + "requirejs":true, + "hasModule":true, + "Blob":true, + "File":true}, + "rules": { + "block-scoped-var": 2, + "dot-notation": 0, + "eqeqeq": [ + 2, + "allow-null" + ], + "guard-for-in": 2, + "no-bitwise": 2, + "no-caller": 2, + "no-cond-assign": 0, + "no-debugger": 2, + "no-empty": 0, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-parens": 0, + "no-irregular-whitespace": 2, + "no-iterator": 2, + "no-loop-func": 2, + "no-multi-str": 2, + "no-new": 2, + "no-plusplus": 0, + "no-proto": 2, + "no-script-url": 2, + "no-sequences": 2, + "no-shadow": 2, + "no-undef": 2, + "no-unused-vars": 2, + "no-with": 2, + "semi": [ + 0, + "never" + ], + "strict": 0, + "valid-typeof": 2, + "wrap-iife": [ + 2, + "inside" + ] + }, + "parser": "babel-eslint" +} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 55cc59d193..0000000000 --- a/.jshintrc +++ /dev/null @@ -1,86 +0,0 @@ -{ - "predef":["Ember", - "jQuery", - "$", - "RSVP", - "Discourse", - "Em", - "PreloadStore", - "Handlebars", - "I18n", - "bootbox", - "module", - "moduleFor", - "moduleForComponent", - "Pretender", - "sandbox", - "controllerFor", - "test", - "ok", - "not", - "expect", - "equal", - "blank", - "present", - "visit", - "andThen", - "click", - "currentPath", - "currentRouteName", - "currentURL", - "fillIn", - "keyEvent", - "triggerEvent", - "count", - "exists", - "visible", - "invisible", - "asyncRender", - "selectDropdown", - "asyncTestDiscourse", - "fixture", - "find", - "sinon", - "moment", - "start", - "_", - "alert", - "containsInstance", - "parseHTML", - "deepEqual", - "notEqual", - "define", - "require", - "requirejs", - "hasModule", - "Blob", - "File"], - "node" : false, - "browser" : true, - "boss" : true, - "curly": false, - "debug": false, - "devel": false, - "eqeqeq": true, - "evil": true, - "forin": false, - "immed": false, - "laxbreak": false, - "newcap": true, - "noarg": true, - "noempty": false, - "nonew": false, - "nomen": false, - "onevar": false, - "plusplus": false, - "regexp": false, - "undef": true, - "unused": true, - "sub": true, - "strict": false, - "white": false, - "eqnull": true, - "quotmark": false, - "lastsemic": true, - "esnext": true -} diff --git a/.travis.yml b/.travis.yml index 352361f0f7..62961abc4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,12 @@ env: addons: postgresql: 9.3 + apt: + packages: + - gifsicle + - jpegoptim + - optipng + - jhead matrix: allow_failures: @@ -23,18 +29,23 @@ rvm: - 2.0.0 - 2.1 - 2.2 - - rbx-2 services: - redis-server sudo: false -cache: bundler +cache: + directories: + - vendor/bundle before_install: - - npm i -g jshint - - jshint . + - gem install bundler + - npm i -g eslint babel-eslint + - eslint app/assets/javascripts + - eslint --ext .es6 app/assets/javascripts + - eslint --ext .es6 test/javascripts + - eslint test/javascripts before_script: - bundle exec rake db:create db:migrate diff --git a/Brewfile b/Brewfile index 2f0e8f764e..ee7378b71c 100644 --- a/Brewfile +++ b/Brewfile @@ -1,22 +1,19 @@ # Install development dependencies on Mac OS X using Homebrew (http://mxcl.github.com/homebrew) -# ensure that Homebrew's sources are up to date -update - # add this repo to Homebrew's sources -tap homebrew/dupes +tap 'homebrew/dupes' # install the gcc compiler required for ruby -install apple-gcc42 +brew 'apple-gcc42' # you probably already have git installed; ensure that it is the latest version -install git +brew 'git' # install the PostgreSQL database -install postgresql +brew 'postgresql' # install the Redis datastore -install redis +brew 'redis' # install headless Javascript testing library -install phantomjs +brew 'phantomjs' diff --git a/Gemfile b/Gemfile index 539bc0d34c..98cdfdd790 100644 --- a/Gemfile +++ b/Gemfile @@ -40,7 +40,7 @@ gem 'active_model_serializers', '~> 0.8.3' gem 'onebox' gem 'ember-rails' -gem 'ember-source', '1.11.3.1' +gem 'ember-source', '1.12.1' gem 'handlebars-source', '2.0.0' gem 'barber' gem 'babel-transpiler' @@ -131,6 +131,7 @@ group :test, :development do gem 'rspec-given' gem 'pry-nav' gem 'spork-rails' + gem 'byebug' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index d10b146ad8..0ba09f4ca8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -46,9 +46,9 @@ GEM multi_json (~> 1.0) aws-sdk-resources (2.0.45) aws-sdk-core (= 2.0.45) - babel-source (4.6.6) - babel-transpiler (0.6.0) - babel-source (>= 4.0, < 5) + babel-source (5.8.19) + babel-transpiler (0.7.0) + babel-source (>= 4.0, < 6) execjs (~> 2.0) barber (0.9.0) ember-source (>= 1.0, < 2) @@ -60,10 +60,13 @@ GEM binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) + byebug (5.0.0) + columnize (= 0.9.0) celluloid (0.16.0) timers (~> 4.0.0) certified (1.0.0) coderay (1.1.0) + columnize (0.9.0) connection_pool (2.2.0) crass (1.0.1) daemons (1.2.2) @@ -86,7 +89,7 @@ GEM ember-source (>= 1.1.0) jquery-rails (>= 1.0.17) railties (>= 3.1) - ember-source (1.11.3.1) + ember-source (1.12.1) erubis (2.7.0) eventmachine (1.0.7) excon (0.45.3) @@ -145,7 +148,7 @@ GEM thor (~> 0.15) libv8 (3.16.14.7) listen (0.7.3) - logster (0.8.4.5.pre) + logster (1.0.0.3.pre) lru_redux (1.1.0) mail (2.5.4) mime-types (~> 1.16) @@ -324,12 +327,12 @@ GEM shoulda-context (1.2.1) shoulda-matchers (2.7.0) activesupport (>= 3.0.0) - sidekiq (3.3.4) - celluloid (>= 0.16.0) - connection_pool (>= 2.1.1) - json - redis (>= 3.0.6) - redis-namespace (>= 1.3.1) + sidekiq (3.4.2) + celluloid (~> 0.16.0) + connection_pool (~> 2.2, >= 2.2.0) + json (~> 1.0) + redis (~> 3.2, >= 3.2.1) + redis-namespace (~> 1.5, >= 1.5.2) simple-rss (1.3.1) simplecov (0.9.1) docile (~> 1.1.0) @@ -397,11 +400,12 @@ DEPENDENCIES barber better_errors binding_of_caller + byebug certified discourse-qunit-rails email_reply_parser ember-rails - ember-source (= 1.11.3.1) + ember-source (= 1.12.1) excon fabrication (= 2.9.8) fakeweb (~> 1.3.0) @@ -481,6 +485,3 @@ DEPENDENCIES uglifier unf unicorn - -BUNDLED WITH - 1.10.3 diff --git a/app/assets/javascripts/admin.js.erb b/app/assets/javascripts/admin.js.erb index ce47046a21..41f0315deb 100644 --- a/app/assets/javascripts/admin.js.erb +++ b/app/assets/javascripts/admin.js.erb @@ -2,4 +2,12 @@ require_asset("main_include_admin.js") DiscoursePluginRegistry.admin_javascripts.each { |js| require_asset(js) } + +DiscoursePluginRegistry.each_globbed_asset(admin: true) do |f, ext| + if File.directory?(f) + depend_on(f) + elsif f.to_s.end_with?(".#{ext}") + require_asset(f) + end +end %> diff --git a/app/assets/javascripts/admin/adapters/embedding.js.es6 b/app/assets/javascripts/admin/adapters/embedding.js.es6 new file mode 100644 index 0000000000..c8985cfdca --- /dev/null +++ b/app/assets/javascripts/admin/adapters/embedding.js.es6 @@ -0,0 +1,7 @@ +import RestAdapter from 'discourse/adapters/rest'; + +export default RestAdapter.extend({ + pathFor() { + return "/admin/customize/embedding"; + } +}); diff --git a/app/assets/javascripts/admin/components/embeddable-host.js.es6 b/app/assets/javascripts/admin/components/embeddable-host.js.es6 new file mode 100644 index 0000000000..f33c750965 --- /dev/null +++ b/app/assets/javascripts/admin/components/embeddable-host.js.es6 @@ -0,0 +1,63 @@ +import { bufferedProperty } from 'discourse/mixins/buffered-content'; +import computed from 'ember-addons/ember-computed-decorators'; +import { on, observes } from 'ember-addons/ember-computed-decorators'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; + +export default Ember.Component.extend(bufferedProperty('host'), { + editToggled: false, + tagName: 'tr', + categoryId: null, + + editing: Ember.computed.or('host.isNew', 'editToggled'), + + @on('didInsertElement') + @observes('editing') + _focusOnInput() { + Ember.run.schedule('afterRender', () => { this.$('.host-name').focus(); }); + }, + + @computed('buffered.host', 'host.isSaving') + cantSave(host, isSaving) { + return isSaving || Ember.isEmpty(host); + }, + + actions: { + edit() { + this.set('categoryId', this.get('host.category.id')); + this.set('editToggled', true); + }, + + save() { + if (this.get('cantSave')) { return; } + + const props = this.get('buffered').getProperties('host'); + props.category_id = this.get('categoryId'); + + const host = this.get('host'); + host.save(props).then(() => { + host.set('category', Discourse.Category.findById(this.get('categoryId'))); + this.set('editToggled', false); + }).catch(popupAjaxError); + }, + + delete() { + bootbox.confirm(I18n.t('admin.embedding.confirm_delete'), (result) => { + if (result) { + this.get('host').destroyRecord().then(() => { + this.sendAction('deleteHost', this.get('host')); + }); + } + }); + }, + + cancel() { + const host = this.get('host'); + if (host.get('isNew')) { + this.sendAction('deleteHost', host); + } else { + this.rollbackBuffer(); + this.set('editToggled', false); + } + } + } +}); diff --git a/app/assets/javascripts/admin/components/embedding-setting.js.es6 b/app/assets/javascripts/admin/components/embedding-setting.js.es6 new file mode 100644 index 0000000000..904afacfee --- /dev/null +++ b/app/assets/javascripts/admin/components/embedding-setting.js.es6 @@ -0,0 +1,23 @@ +import computed from 'ember-addons/ember-computed-decorators'; + +export default Ember.Component.extend({ + classNames: ['embed-setting'], + + @computed('field') + inputId(field) { return field.dasherize(); }, + + @computed('field') + translationKey(field) { return `admin.embedding.${field}`; }, + + @computed('type') + isCheckbox(type) { return type === "checkbox"; }, + + @computed('value') + checked: { + get(value) { return !!value; }, + set(value) { + this.set('value', value); + return value; + } + } +}); diff --git a/app/assets/javascripts/admin/components/highlighted-code.js.es6 b/app/assets/javascripts/admin/components/highlighted-code.js.es6 new file mode 100644 index 0000000000..4fc413fd89 --- /dev/null +++ b/app/assets/javascripts/admin/components/highlighted-code.js.es6 @@ -0,0 +1,12 @@ +import { on, observes } from 'ember-addons/ember-computed-decorators'; +import highlightSyntax from 'discourse/lib/highlight-syntax'; + +export default Ember.Component.extend({ + + @on('didInsertElement') + @observes('code') + _refresh: function() { + highlightSyntax(this.$()); + } + +}); diff --git a/app/assets/javascripts/admin/components/site-setting.js.es6 b/app/assets/javascripts/admin/components/site-setting.js.es6 index 10925e8a2e..93e65743c7 100644 --- a/app/assets/javascripts/admin/components/site-setting.js.es6 +++ b/app/assets/javascripts/admin/components/site-setting.js.es6 @@ -2,8 +2,9 @@ import BufferedContent from 'discourse/mixins/buffered-content'; import ScrollTop from 'discourse/mixins/scroll-top'; import SiteSetting from 'admin/models/site-setting'; import { propertyNotEqual } from 'discourse/lib/computed'; +import computed from 'ember-addons/ember-computed-decorators'; -const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list']; +const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list', 'category_list']; export default Ember.Component.extend(BufferedContent, ScrollTop, { classNameBindings: [':row', ':setting', 'setting.overridden', 'typeClass'], @@ -11,41 +12,32 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, { dirty: propertyNotEqual('buffered.value', 'setting.value'), validationMessage: null, - preview: function() { - const preview = this.get('setting.preview'); + @computed("setting.preview", "buffered.value") + preview(preview, value) { if (preview) { - return new Handlebars.SafeString("
" + - preview.replace(/\{\{value\}\}/g, this.get('buffered.value')) + - "
"); + return new Handlebars.SafeString("
" + preview.replace(/\{\{value\}\}/g, value) + "
"); } - }.property('buffered.value'), + }, - typeClass: function() { - return this.get('partialType').replace("_", "-"); - }.property('partialType'), + @computed('componentType') + typeClass(componentType) { + return componentType.replace("_", "-"); + }, - enabled: function(key, value) { - if (arguments.length > 1) { - this.set('buffered.value', value ? 'true' : 'false'); - } + @computed("setting.setting") + settingName(setting) { + return setting.replace(/\_/g, ' '); + }, - const bufferedValue = this.get('buffered.value'); - if (Ember.isEmpty(bufferedValue)) { return false; } - return bufferedValue === 'true'; - }.property('buffered.value'), + @computed("setting.type") + componentType(type) { + return CustomTypes.indexOf(type) !== -1 ? type : 'string'; + }, - settingName: function() { - return this.get('setting.setting').replace(/\_/g, ' '); - }.property('setting.setting'), - - partialType: function() { - let type = this.get('setting.type'); - return (CustomTypes.indexOf(type) !== -1) ? type : 'string'; - }.property('setting.type'), - - partialName: function() { - return 'admin/templates/site-settings/' + this.get('partialType'); - }.property('partialType'), + @computed("typeClass") + componentName(typeClass) { + return "site-settings/" + typeClass; + }, _watchEnterKey: function() { const self = this; @@ -61,8 +53,8 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, { }.on("willDestroyElement"), _save() { - const setting = this.get('buffered'); - const self = this; + const self = this, + setting = this.get('buffered'); SiteSetting.update(setting.get('setting'), setting.get('value')).then(function() { self.set('validationMessage', null); self.commitBuffer(); diff --git a/app/assets/javascripts/admin/components/site-settings/bool.js.es6 b/app/assets/javascripts/admin/components/site-settings/bool.js.es6 new file mode 100644 index 0000000000..40fcfb354b --- /dev/null +++ b/app/assets/javascripts/admin/components/site-settings/bool.js.es6 @@ -0,0 +1,17 @@ +import computed from "ember-addons/ember-computed-decorators"; + +export default Ember.Component.extend({ + + @computed("value") + enabled: { + get(value) { + if (Ember.isEmpty(value)) { return false; } + return value === "true"; + }, + set(value) { + this.set("value", value ? "true" : "false"); + return value; + } + }, + +}); diff --git a/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 b/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 new file mode 100644 index 0000000000..487239b78f --- /dev/null +++ b/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 @@ -0,0 +1,16 @@ +import computed from "ember-addons/ember-computed-decorators"; + +export default Ember.Component.extend({ + + @computed("value") + selectedCategories: { + get(value) { + return Discourse.Category.findByIds(value.split("|")); + }, + set(value) { + this.set("value", value.mapBy("id").join("|")); + return value; + } + } + +}); diff --git a/app/assets/javascripts/admin/controllers/admin-backups-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-backups-index.js.es6 index fb052e6fc5..1617e6133a 100644 --- a/app/assets/javascripts/admin/controllers/admin-backups-index.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-backups-index.js.es6 @@ -1,8 +1,6 @@ export default Ember.ArrayController.extend({ needs: ["adminBackups"], - status: Em.computed.alias("controllers.adminBackups"), - isOperationRunning: Ember.computed.alias("status.model.isOperationRunning"), - restoreDisabled: Ember.computed.alias("status.model.restoreDisabled"), + status: Ember.computed.alias("controllers.adminBackups"), uploadLabel: function() { return I18n.t("admin.backups.upload.label"); }.property(), diff --git a/app/assets/javascripts/admin/controllers/admin-backups.js.es6 b/app/assets/javascripts/admin/controllers/admin-backups.js.es6 index 05aa974150..a429883378 100644 --- a/app/assets/javascripts/admin/controllers/admin-backups.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-backups.js.es6 @@ -1,4 +1,4 @@ -export default Ember.ObjectController.extend({ +export default Ember.Controller.extend({ noOperationIsRunning: Ember.computed.not("model.isOperationRunning"), rollbackEnabled: Ember.computed.and("model.canRollback", "model.restoreEnabled", "noOperationIsRunning"), rollbackDisabled: Ember.computed.not("rollbackEnabled") diff --git a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 index 15ba6bc011..a44b6a0b79 100644 --- a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 @@ -2,7 +2,7 @@ import { popupAjaxError } from 'discourse/lib/ajax-error'; import BufferedContent from 'discourse/mixins/buffered-content'; import { propertyNotEqual } from 'discourse/lib/computed'; -export default Ember.ObjectController.extend(BufferedContent, { +export default Ember.Controller.extend(BufferedContent, { needs: ['admin-badges'], saving: false, savingStatus: '', diff --git a/app/assets/javascripts/admin/controllers/admin-email-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-index.js.es6 index 341ca4f652..b4006391b2 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-index.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-index.js.es6 @@ -1,6 +1,4 @@ -import DiscourseController from 'discourse/controllers/controller'; - -export default DiscourseController.extend({ +export default Ember.Controller.extend({ /** Is the "send test email" button disabled? diff --git a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 index 84d1f3e4b5..f259acba84 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-preview-digest.js.es6 @@ -1,20 +1,17 @@ -import ObjectController from 'discourse/controllers/object'; - -export default ObjectController.extend({ +export default Ember.Controller.extend({ actions: { - refresh: function() { - var model = this.get('model'), - self = this; + refresh() { + const model = this.get('model'); - self.set('loading', true); - Discourse.EmailPreview.findDigest(this.get('lastSeen')).then(function (email) { + this.set('loading', true); + Discourse.EmailPreview.findDigest(this.get('lastSeen')).then(email => { model.setProperties(email.getProperties('html_content', 'text_content')); - self.set('loading', false); + this.set('loading', false); }); }, - toggleShowHtml: function() { + toggleShowHtml() { this.toggleProperty('showHtml'); } } diff --git a/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 index 0b23e90268..a03bd8212d 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 @@ -1,8 +1,8 @@ -import DiscourseController from 'discourse/controllers/controller'; +import debounce from 'discourse/lib/debounce'; -export default DiscourseController.extend({ +export default Ember.Controller.extend({ - filterEmailLogs: Discourse.debounce(function() { + filterEmailLogs: debounce(function() { var self = this; Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) { self.set("model", logs); diff --git a/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 index 9e3affff6a..1d83f14c6d 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 @@ -1,7 +1,7 @@ -import DiscourseController from 'discourse/controllers/controller'; +import debounce from 'discourse/lib/debounce'; -export default DiscourseController.extend({ - filterEmailLogs: Discourse.debounce(function() { +export default Ember.Controller.extend({ + filterEmailLogs: debounce(function() { var self = this; Discourse.EmailLog.findAll(this.get("filter")).then(function(logs) { self.set("model", logs); diff --git a/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 b/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 new file mode 100644 index 0000000000..780c61f3f9 --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 @@ -0,0 +1,55 @@ +import computed from 'ember-addons/ember-computed-decorators'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; + +export default Ember.Controller.extend({ + saved: false, + embedding: null, + + // show settings if we have at least one created host + @computed('embedding.embeddable_hosts.@each.isCreated') + showSecondary() { + const hosts = this.get('embedding.embeddable_hosts'); + return hosts.length && hosts.findProperty('isCreated'); + }, + + @computed('embedding.base_url') + embeddingCode(baseUrl) { + + const html = +`
+ +`; + + return html; + }, + + actions: { + saveChanges() { + const embedding = this.get('embedding'); + const updates = embedding.getProperties(embedding.get('fields')); + + this.set('saved', false); + this.get('embedding').update(updates).then(() => { + this.set('saved', true); + }).catch(popupAjaxError); + }, + + addHost() { + const host = this.store.createRecord('embeddable-host'); + this.get('embedding.embeddable_hosts').pushObject(host); + }, + + deleteHost(host) { + this.get('embedding.embeddable_hosts').removeObject(host); + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-group.js.es6 b/app/assets/javascripts/admin/controllers/admin-group.js.es6 index 93213e2c66..dee7c45bb8 100644 --- a/app/assets/javascripts/admin/controllers/admin-group.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-group.js.es6 @@ -1,7 +1,7 @@ import { popupAjaxError } from 'discourse/lib/ajax-error'; import { propertyEqual } from 'discourse/lib/computed'; -export default Em.ObjectController.extend({ +export default Ember.Controller.extend({ needs: ['adminGroupsType'], disableSave: false, diff --git a/app/assets/javascripts/admin/controllers/admin-log-screened-ip-address.js.es6 b/app/assets/javascripts/admin/controllers/admin-log-screened-ip-address.js.es6 index 81486978a4..199296d823 100644 --- a/app/assets/javascripts/admin/controllers/admin-log-screened-ip-address.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-log-screened-ip-address.js.es6 @@ -1,4 +1,4 @@ -export default Ember.ObjectController.extend({ +export default Ember.Controller.extend({ editing: false, savedIpAddress: null, diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 index 0ae12ff2c5..987b07a3b6 100644 --- a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 @@ -1,3 +1,4 @@ +import debounce from 'discourse/lib/debounce'; import { outputExportResult } from 'discourse/lib/export-result'; import { exportEntity } from 'discourse/lib/export-csv'; @@ -6,7 +7,7 @@ export default Ember.ArrayController.extend({ itemController: 'admin-log-screened-ip-address', filter: null, - show: Discourse.debounce(function() { + show: debounce(function() { var self = this; self.set('loading', true); Discourse.ScreenedIpAddress.findAll(this.get("filter")).then(function(result) { diff --git a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 index e03e5ebda4..a0d38e7b8c 100644 --- a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 @@ -1,8 +1,10 @@ +import debounce from 'discourse/lib/debounce'; + export default Ember.ArrayController.extend({ loading: false, filter: null, - show: Discourse.debounce(function() { + show: debounce(function() { var self = this; self.set('loading', true); Discourse.Permalink.findAll(self.get("filter")).then(function(result) { diff --git a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 index 1bf93fef7c..e964d17a25 100644 --- a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 @@ -1,4 +1,4 @@ -export default Ember.ObjectController.extend({ +export default Ember.Controller.extend({ viewMode: 'table', viewingTable: Em.computed.equal('viewMode', 'table'), viewingBarChart: Em.computed.equal('viewMode', 'barChart'), diff --git a/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6 index 37bc9b3765..b16db34e3e 100644 --- a/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6 @@ -1,4 +1,4 @@ -export default Ember.ObjectController.extend({ +export default Ember.Controller.extend({ categoryNameKey: null, needs: ['adminSiteSettings'], diff --git a/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 index da32c3f5eb..97b1c9ace9 100644 --- a/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 @@ -1,13 +1,13 @@ -import Presence from 'discourse/mixins/presence'; +import debounce from 'discourse/lib/debounce'; -export default Ember.ArrayController.extend(Presence, { +export default Ember.ArrayController.extend({ filter: null, onlyOverridden: false, filtered: Ember.computed.notEmpty('filter'), filterContentNow: function(category) { // If we have no content, don't bother filtering anything - if (!this.present('allSiteSettings')) return; + if (!!Ember.isEmpty(this.get('allSiteSettings'))) return; let filter; if (this.get('filter')) { @@ -50,7 +50,7 @@ export default Ember.ArrayController.extend(Presence, { this.transitionToRoute("adminSiteSettingsCategory", category || "all_results"); }, - filterContent: Discourse.debounce(function() { + filterContent: debounce(function() { if (this.get("_skipBounce")) { this.set("_skipBounce", false); } else { @@ -64,6 +64,10 @@ export default Ember.ArrayController.extend(Presence, { filter: '', onlyOverridden: false }); + }, + + toggleMenu() { + $('.admin-detail').toggleClass('mobile-closed mobile-open'); } } diff --git a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 index 5e6bb325fd..b85fbaf069 100644 --- a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 @@ -1,25 +1,18 @@ -/** - This controller supports the interface for granting and revoking badges from - individual users. +import UserBadge from 'discourse/models/user-badge'; - @class AdminUserBadgesController - @extends Ember.ArrayController - @namespace Discourse - @module Discourse -**/ export default Ember.ArrayController.extend({ needs: ["adminUser"], - user: Em.computed.alias('controllers.adminUser'), + user: Em.computed.alias('controllers.adminUser.model'), sortProperties: ['granted_at'], sortAscending: false, groupedBadges: function(){ - const badges = this.get('model'); + const allBadges = this.get('model'); - var grouped = _.groupBy(badges, badge => badge.badge_id); + var grouped = _.groupBy(allBadges, badge => badge.badge_id); var expanded = []; - const expandedBadges = badges.get('expandedBadges'); + const expandedBadges = allBadges.get('expandedBadges'); _(grouped).each(function(badges){ var lastGranted = badges[0].granted_at; @@ -95,7 +88,7 @@ export default Ember.ArrayController.extend({ **/ grantBadge: function(badgeId) { var self = this; - Discourse.UserBadge.grant(badgeId, this.get('user.username'), this.get('badgeReason')).then(function(userBadge) { + UserBadge.grant(badgeId, this.get('user.username'), this.get('badgeReason')).then(function(userBadge) { self.set('badgeReason', ''); self.pushObject(userBadge); Ember.run.next(function() { @@ -111,12 +104,6 @@ export default Ember.ArrayController.extend({ }); }, - /** - Revoke the selected userBadge. - - @method revokeBadge - @param {Discourse.UserBadge} userBadge the `Discourse.UserBadge` instance that needs to be revoked. - **/ revokeBadge: function(userBadge) { var self = this; return bootbox.confirm(I18n.t("admin.badges.revoke_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) { diff --git a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 index 339f34e247..fdea272ab1 100644 --- a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 @@ -1,8 +1,7 @@ -import ObjectController from 'discourse/controllers/object'; import CanCheckEmails from 'discourse/mixins/can-check-emails'; import { propertyNotEqual, setting } from 'discourse/lib/computed'; -export default ObjectController.extend(CanCheckEmails, { +export default Ember.Controller.extend(CanCheckEmails, { editingTitle: false, originalPrimaryGroupId: null, availableGroups: null, @@ -37,8 +36,8 @@ export default ObjectController.extend(CanCheckEmails, { saveTitle() { const self = this; - return Discourse.ajax("/users/" + this.get('username').toLowerCase(), { - data: {title: this.get('title')}, + return Discourse.ajax("/users/" + this.get('model.username').toLowerCase(), { + data: {title: this.get('model.title')}, type: 'PUT' }).catch(function(e) { bootbox.alert(I18n.t("generic_error_with_reason", {error: "http: " + e.status + " - " + e.body})); @@ -66,7 +65,7 @@ export default ObjectController.extend(CanCheckEmails, { savePrimaryGroup() { const self = this; - return Discourse.ajax("/admin/users/" + this.get('id') + "/primary_group", { + return Discourse.ajax("/admin/users/" + this.get('model.id') + "/primary_group", { type: 'PUT', data: {primary_group_id: this.get('model.primary_group_id')} }).then(function () { diff --git a/app/assets/javascripts/admin/controllers/admin-user.js.es6 b/app/assets/javascripts/admin/controllers/admin-user.js.es6 index 33f6459f8e..77c79b724a 100644 --- a/app/assets/javascripts/admin/controllers/admin-user.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-user.js.es6 @@ -1,3 +1 @@ -import ObjectController from 'discourse/controllers/object'; - -export default ObjectController.extend(); +export default Ember.Controller.extend(); diff --git a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 index dcca2e31ba..a0eaf6e162 100644 --- a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 @@ -1,3 +1,4 @@ +import debounce from 'discourse/lib/debounce'; import { i18n } from 'discourse/lib/computed'; export default Ember.ArrayController.extend({ @@ -33,7 +34,7 @@ export default Ember.ArrayController.extend({ return I18n.t('admin.users.titles.' + this.get('query')); }.property('query'), - _filterUsers: Discourse.debounce(function() { + _filterUsers: debounce(function() { this._refreshUsers(); }, 250).observes('listFilter'), diff --git a/app/assets/javascripts/admin/controllers/admin.js.es6 b/app/assets/javascripts/admin/controllers/admin.js.es6 index ae2b81f087..3bdfbe6b50 100644 --- a/app/assets/javascripts/admin/controllers/admin.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin.js.es6 @@ -1,6 +1,4 @@ -import DiscourseController from 'discourse/controllers/controller'; - -export default DiscourseController.extend({ +export default Ember.Controller.extend({ showBadges: function() { return this.get('currentUser.admin') && this.siteSettings.enable_badges; }.property() diff --git a/app/assets/javascripts/admin/controllers/modals/admin-agree-flag.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-agree-flag.js.es6 index 635b8c87fe..2924eb6699 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-agree-flag.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-agree-flag.js.es6 @@ -1,7 +1,6 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; -import ObjectController from 'discourse/controllers/object'; -export default ObjectController.extend(ModalFunctionality, { +export default Ember.Controller.extend(ModalFunctionality, { needs: ["admin-flags-list"], _agreeFlag: function (actionOnPost) { diff --git a/app/assets/javascripts/admin/controllers/modals/admin-delete-flag.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-delete-flag.js.es6 index de26828eca..284b8bfd09 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-delete-flag.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-delete-flag.js.es6 @@ -1,8 +1,6 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; -import ObjectController from 'discourse/controllers/object'; - -export default ObjectController.extend(ModalFunctionality, { +export default Ember.Controller.extend(ModalFunctionality, { needs: ["admin-flags-list"], actions: { diff --git a/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6 index 9d525e9827..1e2ae5adca 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6 @@ -1,5 +1,3 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; -import ObjectController from 'discourse/controllers/object'; - -export default ObjectController.extend(ModalFunctionality); +export default Ember.Controller.extend(ModalFunctionality); diff --git a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 index 1af962e41c..682b1ba25d 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 @@ -1,7 +1,6 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; -import Controller from 'discourse/controllers/controller'; -export default Controller.extend(ModalFunctionality, { +export default Ember.Controller.extend(ModalFunctionality, { needs: ["adminBackupsLogs"], _startBackup: function (withUploads) { diff --git a/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6 index 49999aa092..d3e19de569 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6 @@ -1,7 +1,6 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; -import ObjectController from 'discourse/controllers/object'; -export default ObjectController.extend(ModalFunctionality, { +export default Ember.Controller.extend(ModalFunctionality, { submitDisabled: function() { return (!this.get('reason') || this.get('reason').length < 1); diff --git a/app/assets/javascripts/admin/controllers/modals/change-site-customization-details.js.es6 b/app/assets/javascripts/admin/controllers/modals/change-site-customization-details.js.es6 index 1ef3e217d5..ca6ac31db1 100644 --- a/app/assets/javascripts/admin/controllers/modals/change-site-customization-details.js.es6 +++ b/app/assets/javascripts/admin/controllers/modals/change-site-customization-details.js.es6 @@ -1,7 +1,6 @@ import ModalFunctionality from 'discourse/mixins/modal-functionality'; -import ObjectController from 'discourse/controllers/object'; -export default ObjectController.extend(ModalFunctionality, { +export default Ember.Controller.extend(ModalFunctionality, { previousSelected: Ember.computed.equal('selectedTab', 'previous'), newSelected: Ember.computed.equal('selectedTab', 'new'), diff --git a/app/assets/javascripts/admin/models/backup-status.js.es6 b/app/assets/javascripts/admin/models/backup-status.js.es6 new file mode 100644 index 0000000000..2de301f955 --- /dev/null +++ b/app/assets/javascripts/admin/models/backup-status.js.es6 @@ -0,0 +1,12 @@ +import computed from "ember-addons/ember-computed-decorators"; + +export default Discourse.Model.extend({ + + restoreDisabled: Em.computed.not("restoreEnabled"), + + @computed("allowRestore", "isOperationRunning") + restoreEnabled(allowRestore, isOperationRunning) { + return allowRestore && !isOperationRunning; + } + +}); diff --git a/app/assets/javascripts/admin/models/backup_status.js b/app/assets/javascripts/admin/models/backup_status.js deleted file mode 100644 index e67a34bc3f..0000000000 --- a/app/assets/javascripts/admin/models/backup_status.js +++ /dev/null @@ -1,9 +0,0 @@ -Discourse.BackupStatus = Discourse.Model.extend({ - - restoreDisabled: Em.computed.not("restoreEnabled"), - - restoreEnabled: function() { - return this.get('allowRestore') && !this.get("isOperationRunning"); - }.property("isOperationRunning", "allowRestore") - -}); diff --git a/app/assets/javascripts/admin/models/flagged_post.js b/app/assets/javascripts/admin/models/flagged_post.js index 0696067806..e3a01948ca 100644 --- a/app/assets/javascripts/admin/models/flagged_post.js +++ b/app/assets/javascripts/admin/models/flagged_post.js @@ -47,7 +47,7 @@ Discourse.FlaggedPost = Discourse.Post.extend({ }, wasEdited: function () { - if (this.blank("last_revised_at")) { return false; } + if (Ember.isEmpty(this.get("last_revised_at"))) { return false; } var lastRevisedAt = Date.parse(this.get("last_revised_at")); return _.some(this.get("post_actions"), function (postAction) { return Date.parse(postAction.created_at) < lastRevisedAt; diff --git a/app/assets/javascripts/admin/routes/admin-backups.js.es6 b/app/assets/javascripts/admin/routes/admin-backups.js.es6 index d3b632e525..ac7f963cd4 100644 --- a/app/assets/javascripts/admin/routes/admin-backups.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-backups.js.es6 @@ -50,7 +50,7 @@ export default Discourse.Route.extend({ }, backupStarted() { - this.modelFor("adminBackups").set("isOperationRunning", true); + this.controllerFor("adminBackups").set("isOperationRunning", true); this.transitionTo("admin.backups.logs"); this.send("closeModal"); }, @@ -82,7 +82,7 @@ export default Discourse.Route.extend({ Discourse.User.currentProp("hideReadOnlyAlert", true); backup.restore().then(function() { self.controllerFor("adminBackupsLogs").clear(); - self.modelFor("adminBackups").set("model.isOperationRunning", true); + self.controllerFor("adminBackups").set("model.isOperationRunning", true); self.transitionTo("admin.backups.logs"); }); } diff --git a/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 b/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 index 648730d9b0..c283ff737b 100644 --- a/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 @@ -1,3 +1,4 @@ +import Badge from 'discourse/models/badge'; import showModal from 'discourse/lib/show-modal'; export default Ember.Route.extend({ @@ -7,7 +8,7 @@ export default Ember.Route.extend({ model(params) { if (params.badge_id === "new") { - return Discourse.Badge.create({ + return Badge.create({ name: I18n.t('admin.badges.new_badge') }); } diff --git a/app/assets/javascripts/admin/routes/admin-badges.js.es6 b/app/assets/javascripts/admin/routes/admin-badges.js.es6 index 3d417f53c2..5927437669 100644 --- a/app/assets/javascripts/admin/routes/admin-badges.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-badges.js.es6 @@ -1,3 +1,5 @@ +import Badge from 'discourse/models/badge'; + export default Discourse.Route.extend({ _json: null, @@ -5,7 +7,7 @@ export default Discourse.Route.extend({ var self = this; return Discourse.ajax('/admin/badges.json').then(function(json) { self._json = json; - return Discourse.Badge.createFromJson(json); + return Badge.createFromJson(json); }); }, diff --git a/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 new file mode 100644 index 0000000000..94d48e400d --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 @@ -0,0 +1,16 @@ +export default Discourse.Route.extend({ + + model() { + return Discourse.EmailPreview.findDigest(); + }, + + afterModel(model) { + const controller = this.controllerFor('adminEmailPreviewDigest'); + controller.setProperties({ + model: model, + lastSeen: moment().subtract(7, 'days').format('YYYY-MM-DD'), + showHtml: true + }); + } + +}); diff --git a/app/assets/javascripts/admin/routes/admin-embedding.js.es6 b/app/assets/javascripts/admin/routes/admin-embedding.js.es6 new file mode 100644 index 0000000000..d9a249c60c --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-embedding.js.es6 @@ -0,0 +1,9 @@ +export default Ember.Route.extend({ + model() { + return this.store.find('embedding'); + }, + + setupController(controller, model) { + controller.set('embedding', model); + } +}); 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 047e5d51af..e01d0f8f0d 100644 --- a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-route-map.js.es6 @@ -27,6 +27,7 @@ export default { this.resource('adminUserFields', { path: '/user_fields' }); this.resource('adminEmojis', { path: '/emojis' }); this.resource('adminPermalinks', { path: '/permalinks' }); + this.resource('adminEmbedding', { path: '/embedding' }); }); this.route('api'); diff --git a/app/assets/javascripts/admin/routes/admin-user-badges.js.es6 b/app/assets/javascripts/admin/routes/admin-user-badges.js.es6 new file mode 100644 index 0000000000..205c1647c9 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-user-badges.js.es6 @@ -0,0 +1,26 @@ +import UserBadge from 'discourse/models/user-badge'; +import Badge from 'discourse/models/badge'; + +export default Discourse.Route.extend({ + model() { + const username = this.modelFor('adminUser').get('username'); + return UserBadge.findByUsername(username); + }, + + setupController(controller, model) { + // Find all badges. + controller.set('loading', true); + Badge.findAll().then(function(badges) { + controller.set('badges', badges); + if (badges.length > 0) { + var grantableBadges = controller.get('grantableBadges'); + if (grantableBadges.length > 0) { + controller.set('selectedBadgeId', grantableBadges[0].get('id')); + } + } + controller.set('loading', false); + }); + // Set the model. + controller.set('model', model); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin_email_preview_digest_route.js b/app/assets/javascripts/admin/routes/admin_email_preview_digest_route.js deleted file mode 100644 index 511b56bbfe..0000000000 --- a/app/assets/javascripts/admin/routes/admin_email_preview_digest_route.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - Previews the Email Digests - - @class AdminEmailPreviewDigest - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ - -Discourse.AdminEmailPreviewDigestRoute = Discourse.Route.extend({ - - model: function() { - return Discourse.EmailPreview.findDigest(); - }, - - afterModel: function(model) { - var controller = this.controllerFor('adminEmailPreviewDigest'); - controller.setProperties({ - model: model, - lastSeen: moment().subtract(7, 'days').format('YYYY-MM-DD'), - showHtml: true - }); - } - -}); diff --git a/app/assets/javascripts/admin/routes/admin_user_badges_route.js b/app/assets/javascripts/admin/routes/admin_user_badges_route.js deleted file mode 100644 index f681e6f919..0000000000 --- a/app/assets/javascripts/admin/routes/admin_user_badges_route.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - Shows all of the badges that have been granted to a user, and allow granting and - revoking badges. - - @class AdminUserBadgesRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.AdminUserBadgesRoute = Discourse.Route.extend({ - model: function() { - var username = this.modelFor('adminUser').get('username'); - return Discourse.UserBadge.findByUsername(username); - }, - - setupController: function(controller, model) { - // Find all badges. - controller.set('loading', true); - Discourse.Badge.findAll().then(function(badges) { - controller.set('badges', badges); - if (badges.length > 0) { - var grantableBadges = controller.get('grantableBadges'); - if (grantableBadges.length > 0) { - controller.set('selectedBadgeId', grantableBadges[0].get('id')); - } - } - controller.set('loading', false); - }); - // Set the model. - controller.set('model', model); - } -}); diff --git a/app/assets/javascripts/admin/templates/backups_index.hbs b/app/assets/javascripts/admin/templates/backups_index.hbs index 0b66fcaf73..09bf83bc63 100644 --- a/app/assets/javascripts/admin/templates/backups_index.hbs +++ b/app/assets/javascripts/admin/templates/backups_index.hbs @@ -6,9 +6,9 @@
{{resumable-upload target="/admin/backups/upload" success="uploadSuccess" error="uploadError" uploadText=uploadLabel title="admin.backups.upload.title"}} {{#if site.isReadOnly}} - {{d-button icon="eye" action="toggleReadOnlyMode" disabled=model.isOperationRunning title="admin.backups.read_only.disable.title" label="admin.backups.read_only.disable.label"}} + {{d-button icon="eye" action="toggleReadOnlyMode" disabled=status.model.isOperationRunning title="admin.backups.read_only.disable.title" label="admin.backups.read_only.disable.label"}} {{else}} - {{d-button icon="eye" action="toggleReadOnlyMode" disabled=model.isOperationRunning title="admin.backups.read_only.enable.title" label="admin.backups.read_only.enable.label"}} + {{d-button icon="eye" action="toggleReadOnlyMode" disabled=status.model.isOperationRunning title="admin.backups.read_only.enable.title" label="admin.backups.read_only.enable.label"}} {{/if}}
@@ -20,12 +20,12 @@
{{fa-icon "download"}}{{i18n 'admin.backups.operations.download.label'}} - {{#if model.isOperationRunning}} + {{#if status.model.isOperationRunning}} {{d-button icon="trash-o" action="destroyBackup" actionParam=backup class="btn-danger" disabled="true" title="admin.backups.operations.is_running"}} - {{d-button icon="play" action="startRestore" actionParam=backup disabled=model.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}} + {{d-button icon="play" action="startRestore" actionParam=backup disabled=status.model.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}} {{else}} {{d-button icon="trash-o" action="destroyBackup" actionParam=backup class="btn-danger" title="admin.backups.operations.destroy.title"}} - {{d-button icon="play" action="startRestore" actionParam=backup disabled=model.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}} + {{d-button icon="play" action="startRestore" actionParam=backup disabled=status.model.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}} {{/if}}
diff --git a/app/assets/javascripts/admin/templates/components/embeddable-host.hbs b/app/assets/javascripts/admin/templates/components/embeddable-host.hbs new file mode 100644 index 0000000000..c35d40e1d6 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/embeddable-host.hbs @@ -0,0 +1,19 @@ +{{#if editing}} + + {{input value=buffered.host placeholder="example.com" enter="save" class="host-name"}} + + + {{category-chooser value=categoryId}} + + + {{d-button icon="check" action="save" class="btn-primary" disabled=cantSave}} + {{d-button icon="times" action="cancel" class="btn-danger" disabled=host.isSaving}} + +{{else}} + {{host.host}} + {{category-badge host.category}} + + {{d-button icon="pencil" action="edit"}} + {{d-button icon="trash-o" action="delete" class='btn-danger'}} + +{{/if}} diff --git a/app/assets/javascripts/admin/templates/components/embedding-setting.hbs b/app/assets/javascripts/admin/templates/components/embedding-setting.hbs new file mode 100644 index 0000000000..36dbb88692 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/embedding-setting.hbs @@ -0,0 +1,11 @@ +{{#if isCheckbox}} + +{{else}} + + {{input value=value id=inputId}} +{{/if}} + +
diff --git a/app/assets/javascripts/admin/templates/components/highlighted-code.hbs b/app/assets/javascripts/admin/templates/components/highlighted-code.hbs new file mode 100644 index 0000000000..4d67dd6fd2 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/highlighted-code.hbs @@ -0,0 +1 @@ +
{{code}}
diff --git a/app/assets/javascripts/admin/templates/components/site-setting.hbs b/app/assets/javascripts/admin/templates/components/site-setting.hbs index 15821600ee..be0d4d8a08 100644 --- a/app/assets/javascripts/admin/templates/components/site-setting.hbs +++ b/app/assets/javascripts/admin/templates/components/site-setting.hbs @@ -2,7 +2,7 @@

{{unbound settingName}}

- {{partial partialName}} +{{component componentName setting=setting value=buffered.value validationMessage=validationMessage}}
{{#if dirty}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/bool.hbs b/app/assets/javascripts/admin/templates/components/site-settings/bool.hbs similarity index 100% rename from app/assets/javascripts/admin/templates/site-settings/bool.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/bool.hbs diff --git a/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs new file mode 100644 index 0000000000..621f3fa70e --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs @@ -0,0 +1,3 @@ +{{category-group categories=selectedCategories blacklist=selectedCategories}} +
{{{unbound setting.description}}}
+{{setting-validation-message message=validationMessage}} diff --git a/app/assets/javascripts/admin/templates/site-settings/enum.hbs b/app/assets/javascripts/admin/templates/components/site-settings/enum.hbs similarity index 80% rename from app/assets/javascripts/admin/templates/site-settings/enum.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/enum.hbs index 67cbfc92ac..765a0e20d1 100644 --- a/app/assets/javascripts/admin/templates/site-settings/enum.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/enum.hbs @@ -1,4 +1,4 @@ -{{combo-box valueAttribute="value" content=setting.validValues value=buffered.value none=setting.allowsNone}} +{{combo-box valueAttribute="value" content=setting.validValues value=value none=setting.allowsNone}} {{preview}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/url_list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs similarity index 60% rename from app/assets/javascripts/admin/templates/site-settings/url_list.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs index ec8ecaf395..5107f5b4af 100644 --- a/app/assets/javascripts/admin/templates/site-settings/url_list.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs @@ -1,3 +1,3 @@ -{{value-list values=buffered.value addKey="admin.site_settings.add_url"}} +{{value-list values=value addKey="admin.site_settings.add_host"}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/list.hbs similarity index 54% rename from app/assets/javascripts/admin/templates/site-settings/list.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/list.hbs index bc1cf2b51e..e741bea5ed 100644 --- a/app/assets/javascripts/admin/templates/site-settings/list.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/list.hbs @@ -1,3 +1,3 @@ -{{list-setting settingValue=buffered.value choices=setting.choices settingName=setting.setting}} +{{list-setting settingValue=value choices=setting.choices settingName=setting.setting}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/string.hbs b/app/assets/javascripts/admin/templates/components/site-settings/string.hbs similarity index 62% rename from app/assets/javascripts/admin/templates/site-settings/string.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/string.hbs index f8427094ab..71d7216f27 100644 --- a/app/assets/javascripts/admin/templates/site-settings/string.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/string.hbs @@ -1,3 +1,3 @@ -{{text-field value=buffered.value classNames="input-setting-string"}} +{{text-field value=value classNames="input-setting-string"}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/host_list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs similarity index 60% rename from app/assets/javascripts/admin/templates/site-settings/host_list.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs index 5f0c301d0d..41213777e3 100644 --- a/app/assets/javascripts/admin/templates/site-settings/host_list.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs @@ -1,3 +1,3 @@ -{{value-list values=buffered.value addKey="admin.site_settings.add_host"}} +{{value-list values=value addKey="admin.site_settings.add_url"}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/customize.hbs b/app/assets/javascripts/admin/templates/customize.hbs index 130b75e0ac..8ab4c662e7 100644 --- a/app/assets/javascripts/admin/templates/customize.hbs +++ b/app/assets/javascripts/admin/templates/customize.hbs @@ -5,6 +5,7 @@ {{nav-item route='adminUserFields' label='admin.user_fields.title'}} {{nav-item route='adminEmojis' label='admin.emoji.title'}} {{nav-item route='adminPermalinks' label='admin.permalink.title'}} + {{nav-item route='adminEmbedding' label='admin.embedding.title'}} {{/admin-nav}}
diff --git a/app/assets/javascripts/admin/templates/customize_colors.hbs b/app/assets/javascripts/admin/templates/customize_colors.hbs index 85fc27abb8..4e5dc4a5a2 100644 --- a/app/assets/javascripts/admin/templates/customize_colors.hbs +++ b/app/assets/javascripts/admin/templates/customize_colors.hbs @@ -40,6 +40,93 @@
+
+ Various greys used throught the UI. +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ blend-primary-secondary() +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ blend-primary-secondary() +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ dark-light-diff() +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ dark-light-diff() +
+
+ {{#if colors.length}} diff --git a/app/assets/javascripts/admin/templates/email_preview_digest.hbs b/app/assets/javascripts/admin/templates/email_preview_digest.hbs index 7670d6194b..6d95eb0666 100644 --- a/app/assets/javascripts/admin/templates/email_preview_digest.hbs +++ b/app/assets/javascripts/admin/templates/email_preview_digest.hbs @@ -4,24 +4,22 @@
{{input type="date" value=lastSeen id="last-seen"}} -
-
-
-
- - {{#if showHtml}} - {{i18n 'admin.email.html'}} | {{i18n 'admin.email.text'}} - {{else}} - {{i18n 'admin.email.html'}} | {{i18n 'admin.email.text'}} - {{/if}} +
+ + {{#if showHtml}} + {{i18n 'admin.email.html'}} | {{i18n 'admin.email.text'}} + {{else}} + {{i18n 'admin.email.html'}} | {{i18n 'admin.email.text'}} + {{/if}} +
{{#conditional-loading-spinner condition=loading}} {{#if showHtml}} - {{{html_content}}} + {{{model.html_content}}} {{else}} -
{{{text_content}}}
+
{{{model.text_content}}}
{{/if}} {{/conditional-loading-spinner}} diff --git a/app/assets/javascripts/admin/templates/embedding.hbs b/app/assets/javascripts/admin/templates/embedding.hbs new file mode 100644 index 0000000000..15d021a9c1 --- /dev/null +++ b/app/assets/javascripts/admin/templates/embedding.hbs @@ -0,0 +1,61 @@ +
+ {{#if embedding.embeddable_hosts}} +
+ + + + + + {{#each embedding.embeddable_hosts as |host|}} + {{embeddable-host host=host deleteHost="deleteHost"}} + {{/each}} +
{{i18n "admin.embedding.host"}}{{i18n "admin.embedding.category"}} 
+ {{else}} +

{{i18n "admin.embedding.get_started"}}

+ {{/if}} + + {{d-button label="admin.embedding.add_host" action="addHost" icon="plus" class="btn-primary add-host"}} + + +{{#if showSecondary}} +
+

{{{i18n "admin.embedding.sample"}}}

+ {{highlighted-code code=embeddingCode lang="html"}} +
+ +
+ +
+

{{i18n "admin.embedding.settings"}}

+ + {{embedding-setting field="embed_by_username" value=embedding.embed_by_username}} + {{embedding-setting field="embed_post_limit" value=embedding.embed_post_limit}} + {{embedding-setting field="embed_truncate" value=embedding.embed_truncate type="checkbox"}} +
+ +
+

{{i18n "admin.embedding.feed_settings"}}

+

{{i18n "admin.embedding.feed_description"}}

+ + {{embedding-setting field="feed_polling_enabled" value=embedding.feed_polling_enabled type="checkbox"}} + {{embedding-setting field="feed_polling_url" value=embedding.feed_polling_url}} + {{embedding-setting field="embed_username_key_from_feed" value=embedding.embed_username_key_from_feed}} +
+ +
+

{{i18n "admin.embedding.crawling_settings"}}

+

{{i18n "admin.embedding.crawling_description"}}

+ + {{embedding-setting field="embed_whitelist_selector" value=embedding.embed_whitelist_selector}} + {{embedding-setting field="embed_blacklist_selector" value=embedding.embed_blacklist_selector}} +
+ +
+ {{d-button label="admin.embedding.save" + action="saveChanges" + class="btn-primary embed-save" + disabled=embedding.isSaving}} + + {{#if saved}}{{i18n "saved"}}{{/if}} +
+{{/if}} diff --git a/app/assets/javascripts/admin/templates/site-settings.hbs b/app/assets/javascripts/admin/templates/site-settings.hbs index 823c8d6c52..b7f400a242 100644 --- a/app/assets/javascripts/admin/templates/site-settings.hbs +++ b/app/assets/javascripts/admin/templates/site-settings.hbs @@ -6,6 +6,7 @@
+ {{text-field value=filter placeholderKey="type_to_filter" class="no-blur"}}
@@ -26,7 +27,7 @@ -
+
{{outlet}}
diff --git a/app/assets/javascripts/admin/templates/user_index.hbs b/app/assets/javascripts/admin/templates/user-index.hbs similarity index 96% rename from app/assets/javascripts/admin/templates/user_index.hbs rename to app/assets/javascripts/admin/templates/user-index.hbs index 302db5f4d0..9afd15829a 100644 --- a/app/assets/javascripts/admin/templates/user_index.hbs +++ b/app/assets/javascripts/admin/templates/user-index.hbs @@ -143,19 +143,19 @@
{{i18n 'admin.users.approved'}}
- {{#if approved}} + {{#if model.approved}} {{i18n 'admin.user.approved_by'}} - {{#link-to 'adminUser' approvedBy}}{{avatar approvedBy imageSize="small"}}{{/link-to}} - {{#link-to 'adminUser' approvedBy}}{{approvedBy.username}}{{/link-to}} + {{#link-to 'adminUser' approvedBy}}{{avatar model.approvedBy imageSize="small"}}{{/link-to}} + {{#link-to 'adminUser' approvedBy}}{{model.approvedBy.username}}{{/link-to}} {{else}} {{i18n 'no_value'}} {{/if}}
- {{#if approved}} + {{#if model.approved}} {{i18n 'admin.user.approve_success'}} {{else}} - {{#if can_approve}} + {{#if model.can_approve}}