diff --git a/app/assets/javascripts/admin/adapters/build-plugin.js.es6 b/app/assets/javascripts/admin/adapters/build-plugin.js.es6 index b73bf7ecb1f..0297aaa8be7 100644 --- a/app/assets/javascripts/admin/adapters/build-plugin.js.es6 +++ b/app/assets/javascripts/admin/adapters/build-plugin.js.es6 @@ -1,9 +1,11 @@ -import RestAdapter from 'discourse/adapters/rest'; +import RestAdapter from "discourse/adapters/rest"; export default function buildPluginAdapter(pluginName) { return RestAdapter.extend({ pathFor(store, type, findArgs) { - return "/admin/plugins/" + pluginName + this._super(store, type, findArgs); + return ( + "/admin/plugins/" + pluginName + this._super(store, type, findArgs) + ); } }); } diff --git a/app/assets/javascripts/admin/adapters/customization-base.js.es6 b/app/assets/javascripts/admin/adapters/customization-base.js.es6 index f57240a116f..d1087e70199 100644 --- a/app/assets/javascripts/admin/adapters/customization-base.js.es6 +++ b/app/assets/javascripts/admin/adapters/customization-base.js.es6 @@ -1,4 +1,4 @@ -import RestAdapter from 'discourse/adapters/rest'; +import RestAdapter from "discourse/adapters/rest"; export default RestAdapter.extend({ basePath() { diff --git a/app/assets/javascripts/admin/adapters/embedding.js.es6 b/app/assets/javascripts/admin/adapters/embedding.js.es6 index c8985cfdcae..c1d5eceace8 100644 --- a/app/assets/javascripts/admin/adapters/embedding.js.es6 +++ b/app/assets/javascripts/admin/adapters/embedding.js.es6 @@ -1,4 +1,4 @@ -import RestAdapter from 'discourse/adapters/rest'; +import RestAdapter from "discourse/adapters/rest"; export default RestAdapter.extend({ pathFor() { diff --git a/app/assets/javascripts/admin/adapters/flagged-post.js.es6 b/app/assets/javascripts/admin/adapters/flagged-post.js.es6 index 1a1065f6388..dc44315170f 100644 --- a/app/assets/javascripts/admin/adapters/flagged-post.js.es6 +++ b/app/assets/javascripts/admin/adapters/flagged-post.js.es6 @@ -1,4 +1,4 @@ -import RestAdapter from 'discourse/adapters/rest'; +import RestAdapter from "discourse/adapters/rest"; export default RestAdapter.extend({ pathFor(store, type, findArgs) { @@ -17,20 +17,20 @@ export default RestAdapter.extend({ hasMore: pa.conversation.has_more, response: { excerpt: pa.conversation.response.excerpt, - user: helper.lookup('user', pa.conversation.response.user_id) + user: helper.lookup("user", pa.conversation.response.user_id) } }; if (pa.conversation.reply) { conversation.reply = { excerpt: pa.conversation.reply.excerpt, - user: helper.lookup('user', pa.conversation.reply.user_id) + user: helper.lookup("user", pa.conversation.reply.user_id) }; } conversations.push(conversation); } }); - flag.set('conversations', conversations); + flag.set("conversations", conversations); }); return results; diff --git a/app/assets/javascripts/admin/adapters/site-text.js.es6 b/app/assets/javascripts/admin/adapters/site-text.js.es6 index b547b06f3ca..f362b06fe1d 100644 --- a/app/assets/javascripts/admin/adapters/site-text.js.es6 +++ b/app/assets/javascripts/admin/adapters/site-text.js.es6 @@ -1,2 +1,2 @@ -import CustomizationBase from 'admin/adapters/customization-base'; +import CustomizationBase from "admin/adapters/customization-base"; export default CustomizationBase; diff --git a/app/assets/javascripts/admin/adapters/theme.js.es6 b/app/assets/javascripts/admin/adapters/theme.js.es6 index df9c8830d1a..b98ba3e4230 100644 --- a/app/assets/javascripts/admin/adapters/theme.js.es6 +++ b/app/assets/javascripts/admin/adapters/theme.js.es6 @@ -1,4 +1,4 @@ -import RestAdapter from 'discourse/adapters/rest'; +import RestAdapter from "discourse/adapters/rest"; export default RestAdapter.extend({ basePath() { @@ -7,7 +7,9 @@ export default RestAdapter.extend({ afterFindAll(results) { let map = {}; - results.forEach(theme => {map[theme.id] = theme;}); + results.forEach(theme => { + map[theme.id] = theme; + }); results.forEach(theme => { let mapped = theme.get("child_themes") || []; mapped = mapped.map(t => map[t.id]); diff --git a/app/assets/javascripts/admin/adapters/user-field.js.es6 b/app/assets/javascripts/admin/adapters/user-field.js.es6 index b547b06f3ca..f362b06fe1d 100644 --- a/app/assets/javascripts/admin/adapters/user-field.js.es6 +++ b/app/assets/javascripts/admin/adapters/user-field.js.es6 @@ -1,2 +1,2 @@ -import CustomizationBase from 'admin/adapters/customization-base'; +import CustomizationBase from "admin/adapters/customization-base"; export default CustomizationBase; diff --git a/app/assets/javascripts/admin/adapters/web-hook-event.js.es6 b/app/assets/javascripts/admin/adapters/web-hook-event.js.es6 index 122070ce3e4..4c80ac3ff0c 100644 --- a/app/assets/javascripts/admin/adapters/web-hook-event.js.es6 +++ b/app/assets/javascripts/admin/adapters/web-hook-event.js.es6 @@ -1,7 +1,7 @@ -import RESTAdapter from 'discourse/adapters/rest'; +import RESTAdapter from "discourse/adapters/rest"; export default RESTAdapter.extend({ basePath() { - return '/admin/api/'; + return "/admin/api/"; } }); diff --git a/app/assets/javascripts/admin/adapters/web-hook.js.es6 b/app/assets/javascripts/admin/adapters/web-hook.js.es6 index 122070ce3e4..4c80ac3ff0c 100644 --- a/app/assets/javascripts/admin/adapters/web-hook.js.es6 +++ b/app/assets/javascripts/admin/adapters/web-hook.js.es6 @@ -1,7 +1,7 @@ -import RESTAdapter from 'discourse/adapters/rest'; +import RESTAdapter from "discourse/adapters/rest"; export default RESTAdapter.extend({ basePath() { - return '/admin/api/'; + return "/admin/api/"; } }); diff --git a/app/assets/javascripts/admin/components/ace-editor.js.es6 b/app/assets/javascripts/admin/components/ace-editor.js.es6 index faad36798ad..192bc4b410c 100644 --- a/app/assets/javascripts/admin/components/ace-editor.js.es6 +++ b/app/assets/javascripts/admin/components/ace-editor.js.es6 @@ -1,37 +1,37 @@ -import loadScript from 'discourse/lib/load-script'; -import { observes } from 'ember-addons/ember-computed-decorators'; +import loadScript from "discourse/lib/load-script"; +import { observes } from "ember-addons/ember-computed-decorators"; const LOAD_ASYNC = !Ember.testing; export default Ember.Component.extend({ - mode: 'css', - classNames: ['ace-wrapper'], + mode: "css", + classNames: ["ace-wrapper"], _editor: null, _skipContentChangeEvent: null, disabled: false, - @observes('editorId') + @observes("editorId") editorIdChanged() { - if (this.get('autofocus')) { - this.send('focus'); + if (this.get("autofocus")) { + this.send("focus"); } }, - @observes('content') + @observes("content") contentChanged() { if (this._editor && !this._skipContentChangeEvent) { - this._editor.getSession().setValue(this.get('content')); + this._editor.getSession().setValue(this.get("content")); } }, - @observes('mode') + @observes("mode") modeChanged() { if (LOAD_ASYNC && this._editor && !this._skipContentChangeEvent) { - this._editor.getSession().setMode("ace/mode/" + this.get('mode')); + this._editor.getSession().setMode("ace/mode/" + this.get("mode")); } }, - @observes('disabled') + @observes("disabled") disabledStateChanged() { this.changeDisabledState(); }, @@ -39,7 +39,7 @@ export default Ember.Component.extend({ changeDisabledState() { const editor = this._editor; if (editor) { - const disabled = this.get('disabled'); + const disabled = this.get("disabled"); editor.setOptions({ readOnly: disabled, highlightActiveLine: !disabled, @@ -56,12 +56,11 @@ export default Ember.Component.extend({ } if (this.appEvents) { // xxx: don't run during qunit tests - this.appEvents.off('ace:resize', this, this.resize); + this.appEvents.off("ace:resize", this, this.resize); } - $(window).off('ace:resize'); - - }.on('willDestroyElement'), + $(window).off("ace:resize"); + }.on("willDestroyElement"), resize() { if (this._editor) { @@ -73,37 +72,41 @@ export default Ember.Component.extend({ this._super(); loadScript("/javascripts/ace/ace.js", { scriptTag: true }).then(() => { - window.ace.require(['ace/ace'], loadedAce => { - if (!this.element || this.isDestroying || this.isDestroyed) { return; } - const editor = loadedAce.edit(this.$('.ace')[0]); + window.ace.require(["ace/ace"], loadedAce => { + if (!this.element || this.isDestroying || this.isDestroyed) { + return; + } + const editor = loadedAce.edit(this.$(".ace")[0]); if (LOAD_ASYNC) { editor.setTheme("ace/theme/chrome"); } editor.setShowPrintMargin(false); - editor.setOptions({fontSize: "14px"}); + editor.setOptions({ fontSize: "14px" }); if (LOAD_ASYNC) { - editor.getSession().setMode("ace/mode/" + this.get('mode')); + editor.getSession().setMode("ace/mode/" + this.get("mode")); } - editor.on('change', () => { + editor.on("change", () => { this._skipContentChangeEvent = true; - this.set('content', editor.getSession().getValue()); + this.set("content", editor.getSession().getValue()); this._skipContentChangeEvent = false; }); editor.$blockScrolling = Infinity; - editor.renderer.setScrollMargin(10,10); + editor.renderer.setScrollMargin(10, 10); - this.$().data('editor', editor); + this.$().data("editor", editor); this._editor = editor; this.changeDisabledState(); - $(window).off('ace:resize').on('ace:resize', ()=>{ - this.appEvents.trigger('ace:resize'); - }); + $(window) + .off("ace:resize") + .on("ace:resize", () => { + this.appEvents.trigger("ace:resize"); + }); if (this.appEvents) { // xxx: don't run during qunit tests - this.appEvents.on('ace:resize', ()=>this.resize()); + this.appEvents.on("ace:resize", () => this.resize()); } if (this.get("autofocus")) { diff --git a/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 b/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 index 01f4547b17e..c2f9df52059 100644 --- a/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 +++ b/app/assets/javascripts/admin/components/admin-backups-logs.js.es6 @@ -1,57 +1,64 @@ -import debounce from 'discourse/lib/debounce'; -import { renderSpinner } from 'discourse/helpers/loading-spinner'; -import { escapeExpression } from 'discourse/lib/utilities'; -import { bufferedRender } from 'discourse-common/lib/buffered-render'; +import debounce from "discourse/lib/debounce"; +import { renderSpinner } from "discourse/helpers/loading-spinner"; +import { escapeExpression } from "discourse/lib/utilities"; +import { bufferedRender } from "discourse-common/lib/buffered-render"; -export default Ember.Component.extend(bufferedRender({ - classNames: ["admin-backups-logs"], +export default Ember.Component.extend( + bufferedRender({ + classNames: ["admin-backups-logs"], - init() { - this._super(); - this._reset(); - }, + init() { + this._super(); + this._reset(); + }, - _reset() { - this.setProperties({ formattedLogs: "", index: 0 }); - }, + _reset() { + this.setProperties({ formattedLogs: "", index: 0 }); + }, - _scrollDown() { - const $div = this.$()[0]; - $div.scrollTop = $div.scrollHeight; - }, + _scrollDown() { + const $div = this.$()[0]; + $div.scrollTop = $div.scrollHeight; + }, - _updateFormattedLogs: debounce(function() { - const logs = this.get("logs"); - if (logs.length === 0) { - this._reset(); // reset the cached logs whenever the model is reset - } else { - // do the log formatting only once for HELLish performance - let formattedLogs = this.get("formattedLogs"); - for (let i = this.get("index"), length = logs.length; i < length; i++) { - const date = logs[i].get("timestamp"), - message = escapeExpression(logs[i].get("message")); - formattedLogs += "[" + date + "] " + message + "\n"; + _updateFormattedLogs: debounce(function() { + const logs = this.get("logs"); + if (logs.length === 0) { + this._reset(); // reset the cached logs whenever the model is reset + } else { + // do the log formatting only once for HELLish performance + let formattedLogs = this.get("formattedLogs"); + for (let i = this.get("index"), length = logs.length; i < length; i++) { + const date = logs[i].get("timestamp"), + message = escapeExpression(logs[i].get("message")); + formattedLogs += "[" + date + "] " + message + "\n"; + } + // update the formatted logs & cache index + this.setProperties({ + formattedLogs: formattedLogs, + index: logs.length + }); + // force rerender + this.rerenderBuffer(); } - // update the formatted logs & cache index - this.setProperties({ formattedLogs: formattedLogs, index: logs.length }); - // force rerender - this.rerenderBuffer(); - } - Ember.run.scheduleOnce('afterRender', this, this._scrollDown); - }, 150).observes("logs.[]").on('init'), + Ember.run.scheduleOnce("afterRender", this, this._scrollDown); + }, 150) + .observes("logs.[]") + .on("init"), - buildBuffer(buffer) { - const formattedLogs = this.get("formattedLogs"); - if (formattedLogs && formattedLogs.length > 0) { - buffer.push("
"); - buffer.push(formattedLogs); - buffer.push(""); - } else { - buffer.push("
" + I18n.t("admin.backups.logs.none") + "
"); + buildBuffer(buffer) { + const formattedLogs = this.get("formattedLogs"); + if (formattedLogs && formattedLogs.length > 0) { + buffer.push(""); + buffer.push(formattedLogs); + buffer.push(""); + } else { + buffer.push("
" + I18n.t("admin.backups.logs.none") + "
"); + } + // add a loading indicator + if (this.get("status.isOperationRunning")) { + buffer.push(renderSpinner("small")); + } } - // add a loading indicator - if (this.get("status.isOperationRunning")) { - buffer.push(renderSpinner('small')); - } - } -})); + }) +); diff --git a/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6 b/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6 index 8d43474a9d5..add82cbbe72 100644 --- a/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6 +++ b/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6 @@ -1,33 +1,37 @@ -import { iconHTML } from 'discourse-common/lib/icon-library'; -import { bufferedRender } from 'discourse-common/lib/buffered-render'; +import { iconHTML } from "discourse-common/lib/icon-library"; +import { bufferedRender } from "discourse-common/lib/buffered-render"; -export default Ember.Component.extend(bufferedRender({ - tagName: 'th', - classNames: ['sortable'], - rerenderTriggers: ['order', 'ascending'], +export default Ember.Component.extend( + bufferedRender({ + tagName: "th", + classNames: ["sortable"], + rerenderTriggers: ["order", "ascending"], - buildBuffer(buffer) { - const icon = this.get('icon'); + buildBuffer(buffer) { + const icon = this.get("icon"); - if (icon) { - buffer.push(iconHTML(icon)); + if (icon) { + buffer.push(iconHTML(icon)); + } + + buffer.push(I18n.t(this.get("i18nKey"))); + + if (this.get("field") === this.get("order")) { + buffer.push( + iconHTML(this.get("ascending") ? "chevron-up" : "chevron-down") + ); + } + }, + + click() { + const currentOrder = this.get("order"); + const field = this.get("field"); + + if (currentOrder === field) { + this.set("ascending", this.get("ascending") ? null : true); + } else { + this.setProperties({ order: field, ascending: null }); + } } - - buffer.push(I18n.t(this.get('i18nKey'))); - - if (this.get('field') === this.get('order')) { - buffer.push(iconHTML(this.get('ascending') ? 'chevron-up' : 'chevron-down')); - } - }, - - click() { - const currentOrder = this.get('order'); - const field = this.get('field'); - - if (currentOrder === field) { - this.set('ascending', this.get('ascending') ? null : true); - } else { - this.setProperties({ order: field, ascending: null }); - } - } -})); + }) +); diff --git a/app/assets/javascripts/admin/components/admin-form-row.js.es6 b/app/assets/javascripts/admin/components/admin-form-row.js.es6 index e7cef2edb0c..5159168c303 100644 --- a/app/assets/javascripts/admin/components/admin-form-row.js.es6 +++ b/app/assets/javascripts/admin/components/admin-form-row.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - classNames: ['row'] + classNames: ["row"] }); diff --git a/app/assets/javascripts/admin/components/admin-graph.js.es6 b/app/assets/javascripts/admin/components/admin-graph.js.es6 index 724e9673742..7752230cfb1 100644 --- a/app/assets/javascripts/admin/components/admin-graph.js.es6 +++ b/app/assets/javascripts/admin/components/admin-graph.js.es6 @@ -1,49 +1,56 @@ -import loadScript from 'discourse/lib/load-script'; -import { number } from 'discourse/lib/formatter'; +import loadScript from "discourse/lib/load-script"; +import { number } from "discourse/lib/formatter"; export default Ember.Component.extend({ - tagName: 'canvas', - refreshChart(){ + tagName: "canvas", + refreshChart() { const ctx = this.$()[0].getContext("2d"); const model = this.get("model"); const rawData = this.get("model.data"); var data = { labels: rawData.map(r => r.x), - datasets: [{ - data: rawData.map(r => r.y), - label: model.get('title'), - backgroundColor: "rgba(200,220,240,0.3)", - borderColor: "#08C" - }] + datasets: [ + { + data: rawData.map(r => r.y), + label: model.get("title"), + backgroundColor: "rgba(200,220,240,0.3)", + borderColor: "#08C" + } + ] }; const config = { - type: 'line', + type: "line", data: data, options: { responsive: true, tooltips: { callbacks: { - title: (context) => moment(context[0].xLabel, "YYYY-MM-DD").format("LL") + title: context => + moment(context[0].xLabel, "YYYY-MM-DD").format("LL") } }, scales: { - yAxes: [{ - display: true, - ticks: { - callback: (label) => number(label), - suggestedMin: 0 + yAxes: [ + { + display: true, + ticks: { + callback: label => number(label), + suggestedMin: 0 + } } - }] + ] } - }, + } }; this._chart = new window.Chart(ctx, config); }, - didInsertElement(){ - loadScript("/javascripts/Chart.min.js").then(() => this.refreshChart.apply(this)); + didInsertElement() { + loadScript("/javascripts/Chart.min.js").then(() => + this.refreshChart.apply(this) + ); } }); diff --git a/app/assets/javascripts/admin/components/admin-nav.js.es6 b/app/assets/javascripts/admin/components/admin-nav.js.es6 index 9250c1ae73b..91ad923ffcc 100644 --- a/app/assets/javascripts/admin/components/admin-nav.js.es6 +++ b/app/assets/javascripts/admin/components/admin-nav.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: '' + tagName: "" }); diff --git a/app/assets/javascripts/admin/components/admin-report-counts.js.es6 b/app/assets/javascripts/admin/components/admin-report-counts.js.es6 index 1739a186b34..849d81460a2 100644 --- a/app/assets/javascripts/admin/components/admin-report-counts.js.es6 +++ b/app/assets/javascripts/admin/components/admin-report-counts.js.es6 @@ -1,6 +1,9 @@ export default Ember.Component.extend({ allTime: true, - tagName: 'tr', - reverseColors: Ember.computed.match('report.type', /^(time_to_first_response|topics_with_no_response)$/), - classNameBindings: ['reverseColors'] + tagName: "tr", + reverseColors: Ember.computed.match( + "report.type", + /^(time_to_first_response|topics_with_no_response)$/ + ), + classNameBindings: ["reverseColors"] }); diff --git a/app/assets/javascripts/admin/components/admin-report-per-day-counts.js.es6 b/app/assets/javascripts/admin/components/admin-report-per-day-counts.js.es6 index 25bf94db210..b7620b66cd3 100644 --- a/app/assets/javascripts/admin/components/admin-report-per-day-counts.js.es6 +++ b/app/assets/javascripts/admin/components/admin-report-per-day-counts.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: 'tr' + tagName: "tr" }); diff --git a/app/assets/javascripts/admin/components/admin-report-trust-level-counts.js.es6 b/app/assets/javascripts/admin/components/admin-report-trust-level-counts.js.es6 index 25bf94db210..b7620b66cd3 100644 --- a/app/assets/javascripts/admin/components/admin-report-trust-level-counts.js.es6 +++ b/app/assets/javascripts/admin/components/admin-report-trust-level-counts.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: 'tr' + tagName: "tr" }); diff --git a/app/assets/javascripts/admin/components/admin-user-field-item.js.es6 b/app/assets/javascripts/admin/components/admin-user-field-item.js.es6 index 907f803aed3..64e95cecf98 100644 --- a/app/assets/javascripts/admin/components/admin-user-field-item.js.es6 +++ b/app/assets/javascripts/admin/components/admin-user-field-item.js.es6 @@ -1,97 +1,111 @@ -import UserField from 'admin/models/user-field'; -import { bufferedProperty } from 'discourse/mixins/buffered-content'; -import { popupAjaxError } from 'discourse/lib/ajax-error'; -import { propertyEqual } from 'discourse/lib/computed'; +import UserField from "admin/models/user-field"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { propertyEqual } from "discourse/lib/computed"; -export default Ember.Component.extend(bufferedProperty('userField'), { - editing: Ember.computed.empty('userField.id'), - classNameBindings: [':user-field'], +export default Ember.Component.extend(bufferedProperty("userField"), { + editing: Ember.computed.empty("userField.id"), + classNameBindings: [":user-field"], - cantMoveUp: propertyEqual('userField', 'firstField'), - cantMoveDown: propertyEqual('userField', 'lastField'), + cantMoveUp: propertyEqual("userField", "firstField"), + cantMoveDown: propertyEqual("userField", "lastField"), userFieldsDescription: function() { - return I18n.t('admin.user_fields.description'); + return I18n.t("admin.user_fields.description"); }.property(), bufferedFieldType: function() { - return UserField.fieldTypeById(this.get('buffered.field_type')); - }.property('buffered.field_type'), + return UserField.fieldTypeById(this.get("buffered.field_type")); + }.property("buffered.field_type"), _focusOnEdit: function() { - if (this.get('editing')) { - Ember.run.scheduleOnce('afterRender', this, '_focusName'); + if (this.get("editing")) { + Ember.run.scheduleOnce("afterRender", this, "_focusName"); } - }.observes('editing').on('didInsertElement'), + } + .observes("editing") + .on("didInsertElement"), _focusName: function() { - $('.user-field-name').select(); + $(".user-field-name").select(); }, fieldName: function() { - return UserField.fieldTypeById(this.get('userField.field_type')).get('name'); - }.property('userField.field_type'), + return UserField.fieldTypeById(this.get("userField.field_type")).get( + "name" + ); + }.property("userField.field_type"), flags: function() { const ret = []; - if (this.get('userField.editable')) { - ret.push(I18n.t('admin.user_fields.editable.enabled')); + if (this.get("userField.editable")) { + ret.push(I18n.t("admin.user_fields.editable.enabled")); } - if (this.get('userField.required')) { - ret.push(I18n.t('admin.user_fields.required.enabled')); + if (this.get("userField.required")) { + ret.push(I18n.t("admin.user_fields.required.enabled")); } - if (this.get('userField.show_on_profile')) { - ret.push(I18n.t('admin.user_fields.show_on_profile.enabled')); + if (this.get("userField.show_on_profile")) { + ret.push(I18n.t("admin.user_fields.show_on_profile.enabled")); } - if (this.get('userField.show_on_user_card')) { - ret.push(I18n.t('admin.user_fields.show_on_user_card.enabled')); + if (this.get("userField.show_on_user_card")) { + ret.push(I18n.t("admin.user_fields.show_on_user_card.enabled")); } - return ret.join(', '); - }.property('userField.editable', 'userField.required', 'userField.show_on_profile', 'userField.show_on_user_card'), + return ret.join(", "); + }.property( + "userField.editable", + "userField.required", + "userField.show_on_profile", + "userField.show_on_user_card" + ), actions: { save() { const self = this; - const buffered = this.get('buffered'); - const attrs = buffered.getProperties('name', - 'description', - 'field_type', - 'editable', - 'required', - 'show_on_profile', - 'show_on_user_card', - 'options'); + const buffered = this.get("buffered"); + const attrs = buffered.getProperties( + "name", + "description", + "field_type", + "editable", + "required", + "show_on_profile", + "show_on_user_card", + "options" + ); - this.get('userField').save(attrs).then(function() { - self.set('editing', false); - self.commitBuffer(); - }).catch(popupAjaxError); + this.get("userField") + .save(attrs) + .then(function() { + self.set("editing", false); + self.commitBuffer(); + }) + .catch(popupAjaxError); }, moveUp() { - this.sendAction('moveUpAction', this.get('userField')); + this.sendAction("moveUpAction", this.get("userField")); }, moveDown() { - this.sendAction('moveDownAction', this.get('userField')); + this.sendAction("moveDownAction", this.get("userField")); }, edit() { - this.set('editing', true); + this.set("editing", true); }, destroy() { - this.sendAction('destroyAction', this.get('userField')); + this.sendAction("destroyAction", this.get("userField")); }, cancel() { - const id = this.get('userField.id'); + const id = this.get("userField.id"); if (Ember.isEmpty(id)) { - this.sendAction('destroyAction', this.get('userField')); + this.sendAction("destroyAction", this.get("userField")); } else { this.rollbackBuffer(); - this.set('editing', false); + this.set("editing", false); } } } diff --git a/app/assets/javascripts/admin/components/admin-watched-word.js.es6 b/app/assets/javascripts/admin/components/admin-watched-word.js.es6 index 3c78becb493..d1283e8b3ab 100644 --- a/app/assets/javascripts/admin/components/admin-watched-word.js.es6 +++ b/app/assets/javascripts/admin/components/admin-watched-word.js.es6 @@ -1,19 +1,28 @@ -import { iconHTML } from 'discourse-common/lib/icon-library'; -import { bufferedRender } from 'discourse-common/lib/buffered-render'; +import { iconHTML } from "discourse-common/lib/icon-library"; +import { bufferedRender } from "discourse-common/lib/buffered-render"; -export default Ember.Component.extend(bufferedRender({ - classNames: ['watched-word'], +export default Ember.Component.extend( + bufferedRender({ + classNames: ["watched-word"], - buildBuffer(buffer) { - buffer.push(iconHTML('times')); - buffer.push(' ' + this.get('word.word')); - }, + buildBuffer(buffer) { + buffer.push(iconHTML("times")); + buffer.push(" " + this.get("word.word")); + }, - click() { - this.get('word').destroy().then(() => { - this.sendAction('action', this.get('word')); - }).catch(e => { - bootbox.alert(I18n.t("generic_error_with_reason", {error: `http: ${e.status} - ${e.body}`})); - });; - } -})); + click() { + this.get("word") + .destroy() + .then(() => { + this.sendAction("action", this.get("word")); + }) + .catch(e => { + bootbox.alert( + I18n.t("generic_error_with_reason", { + error: `http: ${e.status} - ${e.body}` + }) + ); + }); + } + }) +); diff --git a/app/assets/javascripts/admin/components/admin-web-hook-event-chooser.js.es6 b/app/assets/javascripts/admin/components/admin-web-hook-event-chooser.js.es6 index 976b483995e..6e91ce55c7b 100644 --- a/app/assets/javascripts/admin/components/admin-web-hook-event-chooser.js.es6 +++ b/app/assets/javascripts/admin/components/admin-web-hook-event-chooser.js.es6 @@ -1,38 +1,40 @@ -import computed from 'ember-addons/ember-computed-decorators'; +import computed from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - classNames: ['hook-event'], - typeName: Ember.computed.alias('type.name'), + classNames: ["hook-event"], + typeName: Ember.computed.alias("type.name"), - @computed('typeName') + @computed("typeName") name(typeName) { return I18n.t(`admin.web_hooks.${typeName}_event.name`); }, - @computed('typeName') + @computed("typeName") details(typeName) { return I18n.t(`admin.web_hooks.${typeName}_event.details`); }, - @computed('model.[]', 'typeName') + @computed("model.[]", "typeName") eventTypeExists(eventTypes, typeName) { return eventTypes.any(event => event.name === typeName); }, - @computed('eventTypeExists') + @computed("eventTypeExists") enabled: { get(eventTypeExists) { return eventTypeExists; }, set(value, eventTypeExists) { - const type = this.get('type'); - const model = this.get('model'); + const type = this.get("type"); + const model = this.get("model"); // add an association when not exists if (value !== eventTypeExists) { if (value) { model.addObject(type); } else { - model.removeObjects(model.filter(eventType => eventType.name === type.name)); + model.removeObjects( + model.filter(eventType => eventType.name === type.name) + ); } } diff --git a/app/assets/javascripts/admin/components/admin-web-hook-event.js.es6 b/app/assets/javascripts/admin/components/admin-web-hook-event.js.es6 index 264e827da61..5191412c298 100644 --- a/app/assets/javascripts/admin/components/admin-web-hook-event.js.es6 +++ b/app/assets/javascripts/admin/components/admin-web-hook-event.js.es6 @@ -1,78 +1,92 @@ -import computed from 'ember-addons/ember-computed-decorators'; -import { ajax } from 'discourse/lib/ajax'; -import { popupAjaxError } from 'discourse/lib/ajax-error'; -import { ensureJSON, plainJSON, prettyJSON } from 'discourse/lib/formatter'; +import computed from "ember-addons/ember-computed-decorators"; +import { ajax } from "discourse/lib/ajax"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { ensureJSON, plainJSON, prettyJSON } from "discourse/lib/formatter"; export default Ember.Component.extend({ - tagName: 'li', + tagName: "li", expandDetails: null, - @computed('model.status') + @computed("model.status") statusColorClasses(status) { - if (!status) return ''; + if (!status) return ""; if (status >= 200 && status <= 299) { - return 'text-successful'; + return "text-successful"; } else { - return 'text-danger'; + return "text-danger"; } }, - @computed('model.created_at') + @computed("model.created_at") createdAt(createdAt) { - return moment(createdAt).format('YYYY-MM-DD HH:mm:ss'); + return moment(createdAt).format("YYYY-MM-DD HH:mm:ss"); }, - @computed('model.duration') + @computed("model.duration") completion(duration) { const seconds = Math.floor(duration / 10.0) / 100.0; - return I18n.t('admin.web_hooks.events.completed_in', { count: seconds }); + return I18n.t("admin.web_hooks.events.completed_in", { count: seconds }); }, actions: { redeliver() { - return bootbox.confirm(I18n.t('admin.web_hooks.events.redeliver_confirm'), I18n.t('no_value'), I18n.t('yes_value'), result => { - if (result) { - ajax(`/admin/api/web_hooks/${this.get('model.web_hook_id')}/events/${this.get('model.id')}/redeliver`, { type: 'POST' }).then(json => { - this.set('model', json.web_hook_event); - }).catch(popupAjaxError); + return bootbox.confirm( + I18n.t("admin.web_hooks.events.redeliver_confirm"), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + ajax( + `/admin/api/web_hooks/${this.get( + "model.web_hook_id" + )}/events/${this.get("model.id")}/redeliver`, + { type: "POST" } + ) + .then(json => { + this.set("model", json.web_hook_event); + }) + .catch(popupAjaxError); + } } - }); + ); }, toggleRequest() { - const expandDetailsKey = 'request'; + const expandDetailsKey = "request"; - if (this.get('expandDetails') !== expandDetailsKey) { - let headers = _.extend({ - 'Request URL': this.get('model.request_url'), - 'Request method': 'POST' - }, ensureJSON(this.get('model.headers'))); + if (this.get("expandDetails") !== expandDetailsKey) { + let headers = _.extend( + { + "Request URL": this.get("model.request_url"), + "Request method": "POST" + }, + ensureJSON(this.get("model.headers")) + ); this.setProperties({ headers: plainJSON(headers), - body: prettyJSON(this.get('model.payload')), + body: prettyJSON(this.get("model.payload")), expandDetails: expandDetailsKey, - bodyLabel: I18n.t('admin.web_hooks.events.payload') + bodyLabel: I18n.t("admin.web_hooks.events.payload") }); } else { - this.set('expandDetails', null); + this.set("expandDetails", null); } }, toggleResponse() { - const expandDetailsKey = 'response'; + const expandDetailsKey = "response"; - if (this.get('expandDetails') !== expandDetailsKey) { + if (this.get("expandDetails") !== expandDetailsKey) { this.setProperties({ - headers: plainJSON(this.get('model.response_headers')), - body: this.get('model.response_body'), + headers: plainJSON(this.get("model.response_headers")), + body: this.get("model.response_body"), expandDetails: expandDetailsKey, - bodyLabel: I18n.t('admin.web_hooks.events.body') + bodyLabel: I18n.t("admin.web_hooks.events.body") }); } else { - this.set('expandDetails', null); + this.set("expandDetails", null); } } } - }); diff --git a/app/assets/javascripts/admin/components/admin-web-hook-status.js.es6 b/app/assets/javascripts/admin/components/admin-web-hook-status.js.es6 index c5f1a4a2447..9e508e904c4 100644 --- a/app/assets/javascripts/admin/components/admin-web-hook-status.js.es6 +++ b/app/assets/javascripts/admin/components/admin-web-hook-status.js.es6 @@ -1,28 +1,32 @@ -import computed from 'ember-addons/ember-computed-decorators'; -import { iconHTML } from 'discourse-common/lib/icon-library'; -import { bufferedRender } from 'discourse-common/lib/buffered-render'; +import computed from "ember-addons/ember-computed-decorators"; +import { iconHTML } from "discourse-common/lib/icon-library"; +import { bufferedRender } from "discourse-common/lib/buffered-render"; -export default Ember.Component.extend(bufferedRender({ - classes: ["text-muted", "text-danger", "text-successful"], - icons: ["circle-o", "times-circle", "circle"], +export default Ember.Component.extend( + bufferedRender({ + classes: ["text-muted", "text-danger", "text-successful"], + icons: ["circle-o", "times-circle", "circle"], - @computed('deliveryStatuses', 'model.last_delivery_status') - status(deliveryStatuses, lastDeliveryStatus) { - return deliveryStatuses.find(s => s.id === lastDeliveryStatus); - }, + @computed("deliveryStatuses", "model.last_delivery_status") + status(deliveryStatuses, lastDeliveryStatus) { + return deliveryStatuses.find(s => s.id === lastDeliveryStatus); + }, - @computed('status.id', 'icons') - icon(statusId, icons) { - return icons[statusId - 1]; - }, + @computed("status.id", "icons") + icon(statusId, icons) { + return icons[statusId - 1]; + }, - @computed('status.id', 'classes') - class(statusId, classes) { - return classes[statusId - 1]; - }, + @computed("status.id", "classes") + class(statusId, classes) { + return classes[statusId - 1]; + }, - buildBuffer(buffer) { - buffer.push(iconHTML(this.get('icon'), { class: this.get('class') })); - buffer.push(I18n.t(`admin.web_hooks.delivery_status.${this.get('status.name')}`)); - } -})); + buildBuffer(buffer) { + buffer.push(iconHTML(this.get("icon"), { class: this.get("class") })); + buffer.push( + I18n.t(`admin.web_hooks.delivery_status.${this.get("status.name")}`) + ); + } + }) +); diff --git a/app/assets/javascripts/admin/components/admin-wrapper.js.es6 b/app/assets/javascripts/admin/components/admin-wrapper.js.es6 index 118728f66ca..034e2a0af43 100644 --- a/app/assets/javascripts/admin/components/admin-wrapper.js.es6 +++ b/app/assets/javascripts/admin/components/admin-wrapper.js.es6 @@ -1,11 +1,11 @@ export default Ember.Component.extend({ didInsertElement() { this._super(); - $('body').addClass('admin-interface'); + $("body").addClass("admin-interface"); }, willDestroyElement() { this._super(); - $('body').removeClass('admin-interface'); + $("body").removeClass("admin-interface"); } }); diff --git a/app/assets/javascripts/admin/components/cancel-link.js.es6 b/app/assets/javascripts/admin/components/cancel-link.js.es6 index 9250c1ae73b..91ad923ffcc 100644 --- a/app/assets/javascripts/admin/components/cancel-link.js.es6 +++ b/app/assets/javascripts/admin/components/cancel-link.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: '' + tagName: "" }); diff --git a/app/assets/javascripts/admin/components/color-input.js.es6 b/app/assets/javascripts/admin/components/color-input.js.es6 index 005c4f5d4ba..17ae5a9296d 100644 --- a/app/assets/javascripts/admin/components/color-input.js.es6 +++ b/app/assets/javascripts/admin/components/color-input.js.es6 @@ -1,4 +1,4 @@ -import {default as loadScript, loadCSS } from 'discourse/lib/load-script'; +import { default as loadScript, loadCSS } from "discourse/lib/load-script"; /** An input field for a color. @@ -8,35 +8,43 @@ import {default as loadScript, loadCSS } from 'discourse/lib/load-script'; @params valid is a boolean indicating if the input field is a valid color. **/ export default Ember.Component.extend({ - classNames: ['color-picker'], + classNames: ["color-picker"], hexValueChanged: function() { - var hex = this.get('hexValue'); - let $text = this.$('input.hex-input'); + var hex = this.get("hexValue"); + let $text = this.$("input.hex-input"); - if (this.get('valid')) { - $text.attr('style', 'color: ' + (this.get('brightnessValue') > 125 ? 'black' : 'white') + '; background-color: #' + hex + ';'); + if (this.get("valid")) { + $text.attr( + "style", + "color: " + + (this.get("brightnessValue") > 125 ? "black" : "white") + + "; background-color: #" + + hex + + ";" + ); - if (this.get('pickerLoaded')) { - this.$('.picker').spectrum({color: "#" + this.get('hexValue')}); + if (this.get("pickerLoaded")) { + this.$(".picker").spectrum({ color: "#" + this.get("hexValue") }); } } else { - $text.attr('style', ''); + $text.attr("style", ""); } - }.observes('hexValue', 'brightnessValue', 'valid'), + }.observes("hexValue", "brightnessValue", "valid"), didInsertElement() { - loadScript('/javascripts/spectrum.js').then(()=>{ - loadCSS('/javascripts/spectrum.css').then(()=>{ - Em.run.schedule('afterRender', ()=>{ - this.$('.picker').spectrum({color: "#" + this.get('hexValue')}) - .on("change.spectrum", (me, color)=>{ - this.set('hexValue', color.toHexString().replace("#","")); - }); - this.set('pickerLoaded', true); + loadScript("/javascripts/spectrum.js").then(() => { + loadCSS("/javascripts/spectrum.css").then(() => { + Em.run.schedule("afterRender", () => { + this.$(".picker") + .spectrum({ color: "#" + this.get("hexValue") }) + .on("change.spectrum", (me, color) => { + this.set("hexValue", color.toHexString().replace("#", "")); + }); + this.set("pickerLoaded", true); }); }); }); - Em.run.schedule('afterRender', ()=>{ + Em.run.schedule("afterRender", () => { this.hexValueChanged(); }); } diff --git a/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 b/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 index 8fae065f7bc..0435f8237e9 100644 --- a/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 +++ b/app/assets/javascripts/admin/components/dashboard-inline-table.js.es6 @@ -9,11 +9,12 @@ export default Ember.Component.extend(AsyncReport, { let payload = this.buildPayload(["total", "prev30Days"]); - return Ember.RSVP.Promise.all(this.get("dataSources").map(dataSource => { - return ajax(dataSource, payload) - .then(response => { + return Ember.RSVP.Promise.all( + this.get("dataSources").map(dataSource => { + return ajax(dataSource, payload).then(response => { this.get("reports").pushObject(this.loadReport(response.report)); }); - })); + }) + ); } }); diff --git a/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 b/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 index 36a95dc15cd..1f0d4b7cba1 100644 --- a/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 +++ b/app/assets/javascripts/admin/components/dashboard-mini-chart.js.es6 @@ -1,7 +1,7 @@ import { ajax } from "discourse/lib/ajax"; import AsyncReport from "admin/mixins/async-report"; import Report from "admin/models/report"; -import { number } from 'discourse/lib/formatter'; +import { number } from "discourse/lib/formatter"; import loadScript from "discourse/lib/load-script"; import { registerTooltip, unregisterTooltip } from "discourse/lib/tooltip"; @@ -9,9 +9,8 @@ function collapseWeekly(data, average) { let aggregate = []; let bucket, i; let offset = data.length % 7; - for(i = offset; i < data.length; i++) { - - if (bucket && (i % 7 === offset)) { + for (i = offset; i < data.length; i++) { + if (bucket && i % 7 === offset) { if (average) { bucket.y = parseFloat((bucket.y / 7.0).toFixed(2)); } @@ -59,12 +58,13 @@ export default Ember.Component.extend(AsyncReport, { this._chart = null; } - return Ember.RSVP.Promise.all(this.get("dataSources").map(dataSource => { - return ajax(dataSource, payload) - .then(response => { + return Ember.RSVP.Promise.all( + this.get("dataSources").map(dataSource => { + return ajax(dataSource, payload).then(response => { this.get("reports").pushObject(this.loadReport(response.report)); }); - })); + }) + ); }, loadReport(report, previousReport) { @@ -77,7 +77,9 @@ export default Ember.Component.extend(AsyncReport, { if (previousReport && previousReport.color.length) { report.color = previousReport.color; } else { - const dataSourceNameIndex = this.get("dataSourceNames").split(",").indexOf(report.type); + const dataSourceNameIndex = this.get("dataSourceNames") + .split(",") + .indexOf(report.type); report.color = this.pickColorAtIndex(dataSourceNameIndex); } @@ -94,13 +96,17 @@ export default Ember.Component.extend(AsyncReport, { const reportsForPeriod = this.get("reportsForPeriod"); - const labels = Ember.makeArray(reportsForPeriod.get("firstObject.data")).map(d => d.x); + const labels = Ember.makeArray( + reportsForPeriod.get("firstObject.data") + ).map(d => d.x); const data = { labels, datasets: reportsForPeriod.map(report => { return { - data: Ember.makeArray(report.data).map(d => Math.round(parseFloat(d.y))), + data: Ember.makeArray(report.data).map(d => + Math.round(parseFloat(d.y)) + ), backgroundColor: "rgba(200,220,240,0.3)", borderColor: report.color }; @@ -129,7 +135,8 @@ export default Ember.Component.extend(AsyncReport, { options: { tooltips: { callbacks: { - title: (context) => moment(context[0].xLabel, "YYYY-MM-DD").format("LL") + title: context => + moment(context[0].xLabel, "YYYY-MM-DD").format("LL") } }, legend: { @@ -146,20 +153,24 @@ export default Ember.Component.extend(AsyncReport, { } }, scales: { - yAxes: [{ - display: true, - ticks: { callback: (label) => number(label) } - }], - xAxes: [{ - display: true, - gridLines: { display: false }, - type: "time", - time: { - parser: "YYYY-MM-DD" + yAxes: [ + { + display: true, + ticks: { callback: label => number(label) } } - }], + ], + xAxes: [ + { + display: true, + gridLines: { display: false }, + type: "time", + time: { + parser: "YYYY-MM-DD" + } + } + ] } - }, + } }; } }); diff --git a/app/assets/javascripts/admin/components/dashboard-table.js.es6 b/app/assets/javascripts/admin/components/dashboard-table.js.es6 index 96b74e6e153..fad090efacb 100644 --- a/app/assets/javascripts/admin/components/dashboard-table.js.es6 +++ b/app/assets/javascripts/admin/components/dashboard-table.js.es6 @@ -9,11 +9,12 @@ export default Ember.Component.extend(AsyncReport, { let payload = this.buildPayload(["total", "prev30Days"]); - return Ember.RSVP.Promise.all(this.get("dataSources").map(dataSource => { - return ajax(dataSource, payload) - .then(response => { + return Ember.RSVP.Promise.all( + this.get("dataSources").map(dataSource => { + return ajax(dataSource, payload).then(response => { this.get("reports").pushObject(this.loadReport(response.report)); }); - })); + }) + ); } }); diff --git a/app/assets/javascripts/admin/components/embeddable-host.js.es6 b/app/assets/javascripts/admin/components/embeddable-host.js.es6 index 70c1ed272cf..7264d42c1c3 100644 --- a/app/assets/javascripts/admin/components/embeddable-host.js.es6 +++ b/app/assets/javascripts/admin/components/embeddable-host.js.es6 @@ -1,63 +1,79 @@ -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'; +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'), { +export default Ember.Component.extend(bufferedProperty("host"), { editToggled: false, - tagName: 'tr', + tagName: "tr", categoryId: null, - editing: Ember.computed.or('host.isNew', 'editToggled'), + editing: Ember.computed.or("host.isNew", "editToggled"), - @on('didInsertElement') - @observes('editing') + @on("didInsertElement") + @observes("editing") _focusOnInput() { - Ember.run.schedule('afterRender', () => { this.$('.host-name').focus(); }); + Ember.run.schedule("afterRender", () => { + this.$(".host-name").focus(); + }); }, - @computed('buffered.host', 'host.isSaving') + @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); + this.set("categoryId", this.get("host.category.id")); + this.set("editToggled", true); }, save() { - if (this.get('cantSave')) { return; } + if (this.get("cantSave")) { + return; + } - const props = this.get('buffered').getProperties('host', 'path_whitelist', 'class_name'); - props.category_id = this.get('categoryId'); + const props = this.get("buffered").getProperties( + "host", + "path_whitelist", + "class_name" + ); + props.category_id = this.get("categoryId"); - const host = this.get('host'); + const host = this.get("host"); - host.save(props).then(() => { - host.set('category', Discourse.Category.findById(this.get('categoryId'))); - this.set('editToggled', false); - }).catch(popupAjaxError); + 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) => { + bootbox.confirm(I18n.t("admin.embedding.confirm_delete"), result => { if (result) { - this.get('host').destroyRecord().then(() => { - this.sendAction('deleteHost', this.get('host')); - }); + 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); + const host = this.get("host"); + if (host.get("isNew")) { + this.sendAction("deleteHost", host); } else { this.rollbackBuffer(); - this.set('editToggled', false); + 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 index f1d31fcf68b..4791e84e357 100644 --- a/app/assets/javascripts/admin/components/embedding-setting.js.es6 +++ b/app/assets/javascripts/admin/components/embedding-setting.js.es6 @@ -1,22 +1,30 @@ -import computed from 'ember-addons/ember-computed-decorators'; +import computed from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - classNames: ['embed-setting'], + classNames: ["embed-setting"], - @computed('field') - inputId(field) { return field.dasherize(); }, + @computed("field") + inputId(field) { + return field.dasherize(); + }, - @computed('field') - translationKey(field) { return `admin.embedding.${field}`; }, + @computed("field") + translationKey(field) { + return `admin.embedding.${field}`; + }, - @computed('type') - isCheckbox(type) { return type === "checkbox"; }, + @computed("type") + isCheckbox(type) { + return type === "checkbox"; + }, - @computed('value') + @computed("value") checked: { - get(value) { return !!value; }, + get(value) { + return !!value; + }, set(value) { - this.set('value', value); + this.set("value", value); return value; } } diff --git a/app/assets/javascripts/admin/components/flag-user-lists.js.es6 b/app/assets/javascripts/admin/components/flag-user-lists.js.es6 index cd843ff7ab6..ae6094c6a75 100644 --- a/app/assets/javascripts/admin/components/flag-user-lists.js.es6 +++ b/app/assets/javascripts/admin/components/flag-user-lists.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - classNames: ['flag-user-lists'] + classNames: ["flag-user-lists"] }); diff --git a/app/assets/javascripts/admin/components/flagged-post-response.js.es6 b/app/assets/javascripts/admin/components/flagged-post-response.js.es6 index e031f33e031..e8dc2a230cd 100644 --- a/app/assets/javascripts/admin/components/flagged-post-response.js.es6 +++ b/app/assets/javascripts/admin/components/flagged-post-response.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - classNames: ['flagged-post-response'] + classNames: ["flagged-post-response"] }); diff --git a/app/assets/javascripts/admin/components/flagged-post-title.js.es6 b/app/assets/javascripts/admin/components/flagged-post-title.js.es6 index 7c1c013375b..4a6fa5d604f 100644 --- a/app/assets/javascripts/admin/components/flagged-post-title.js.es6 +++ b/app/assets/javascripts/admin/components/flagged-post-title.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: 'h3' + tagName: "h3" }); diff --git a/app/assets/javascripts/admin/components/flagged-post.js.es6 b/app/assets/javascripts/admin/components/flagged-post.js.es6 index 8aff3d2a2d1..03edebab6cb 100644 --- a/app/assets/javascripts/admin/components/flagged-post.js.es6 +++ b/app/assets/javascripts/admin/components/flagged-post.js.es6 @@ -1,21 +1,21 @@ -import showModal from 'discourse/lib/show-modal'; -import computed from 'ember-addons/ember-computed-decorators'; +import showModal from "discourse/lib/show-modal"; +import computed from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ adminTools: Ember.inject.service(), expanded: false, - tagName: 'div', + tagName: "div", classNameBindings: [ - ':flagged-post', - 'flaggedPost.hidden:hidden-post', - 'flaggedPost.deleted' + ":flagged-post", + "flaggedPost.hidden:hidden-post", + "flaggedPost.deleted" ], - canAct: Ember.computed.alias('actableFilter'), + canAct: Ember.computed.alias("actableFilter"), - @computed('filter') + @computed("filter") actableFilter(filter) { - return filter === 'active'; + return filter === "active"; }, removeAfter(promise) { @@ -24,7 +24,7 @@ export default Ember.Component.extend({ _spawnModal(name, model, modalClass) { let controller = showModal(name, { model, admin: true, modalClass }); - controller.removeAfter = (p) => this.removeAfter(p); + controller.removeAfter = p => this.removeAfter(p); }, actions: { @@ -33,23 +33,25 @@ export default Ember.Component.extend({ }, disagree() { - this.removeAfter(this.get('flaggedPost').disagreeFlags()); + this.removeAfter(this.get("flaggedPost").disagreeFlags()); }, defer() { - this.removeAfter(this.get('flaggedPost').deferFlags()); + this.removeAfter(this.get("flaggedPost").deferFlags()); }, expand() { - this.get('flaggedPost').expandHidden().then(() => { - this.set('expanded', true); - }); + this.get("flaggedPost") + .expandHidden() + .then(() => { + this.set("expanded", true); + }); }, showModerationHistory() { - this.get('adminTools').showModerationHistory({ - filter: 'post', - post_id: this.get('flaggedPost.id') + this.get("adminTools").showModerationHistory({ + filter: "post", + post_id: this.get("flaggedPost.id") }); } } diff --git a/app/assets/javascripts/admin/components/highlighted-code.js.es6 b/app/assets/javascripts/admin/components/highlighted-code.js.es6 index 4fc413fd898..62cf58f21b2 100644 --- a/app/assets/javascripts/admin/components/highlighted-code.js.es6 +++ b/app/assets/javascripts/admin/components/highlighted-code.js.es6 @@ -1,12 +1,10 @@ -import { on, observes } from 'ember-addons/ember-computed-decorators'; -import highlightSyntax from 'discourse/lib/highlight-syntax'; +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') + @on("didInsertElement") + @observes("code") _refresh: function() { highlightSyntax(this.$()); } - }); diff --git a/app/assets/javascripts/admin/components/inline-edit-checkbox.js.es6 b/app/assets/javascripts/admin/components/inline-edit-checkbox.js.es6 index 5c168760c7f..f14ba622018 100644 --- a/app/assets/javascripts/admin/components/inline-edit-checkbox.js.es6 +++ b/app/assets/javascripts/admin/components/inline-edit-checkbox.js.es6 @@ -1,12 +1,15 @@ -import {default as computed, observes} from "ember-addons/ember-computed-decorators"; +import { + default as computed, + observes +} from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - init(){ + init() { this._super(); this.set("checkedInternal", this.get("checked")); }, - classNames: ['inline-edit'], + classNames: ["inline-edit"], @observes("checked") checkedChanged() { @@ -20,15 +23,15 @@ export default Ember.Component.extend({ @computed("checked", "checkedInternal") changed(checked, checkedInternal) { - return (!!checked) !== (!!checkedInternal); + return !!checked !== !!checkedInternal; }, actions: { - cancelled(){ + cancelled() { this.set("checkedInternal", this.get("checked")); }, - finished(){ + finished() { this.set("checked", this.get("checkedInternal")); this.sendAction(); } diff --git a/app/assets/javascripts/admin/components/ip-lookup.js.es6 b/app/assets/javascripts/admin/components/ip-lookup.js.es6 index a185e4c0b6e..3f06ba38d67 100644 --- a/app/assets/javascripts/admin/components/ip-lookup.js.es6 +++ b/app/assets/javascripts/admin/components/ip-lookup.js.es6 @@ -1,15 +1,17 @@ -import { ajax } from 'discourse/lib/ajax'; -import AdminUser from 'admin/models/admin-user'; +import { ajax } from "discourse/lib/ajax"; +import AdminUser from "admin/models/admin-user"; export default Ember.Component.extend({ classNames: ["ip-lookup"], - city: function () { + city: function() { return [ this.get("location.city"), this.get("location.region"), this.get("location.country") - ].filter(Boolean).join(", "); + ] + .filter(Boolean) + .join(", "); }.property("location.{city,region,country}"), otherAccountsToDelete: function() { @@ -20,14 +22,14 @@ export default Ember.Component.extend({ }.property("other_accounts", "totalOthersWithSameIP"), actions: { - lookup: function () { + lookup: function() { var self = this; this.set("show", true); if (!this.get("location")) { ajax("/admin/users/ip-info", { data: { ip: this.get("ip") } - }).then(function (location) { + }).then(function(location) { self.set("location", Em.Object.create(location)); }); } @@ -36,50 +38,57 @@ export default Ember.Component.extend({ this.set("otherAccountsLoading", true); var data = { - "ip": this.get("ip"), - "exclude": this.get("userId"), - "order": "trust_level DESC" + ip: this.get("ip"), + exclude: this.get("userId"), + order: "trust_level DESC" }; - ajax("/admin/users/total-others-with-same-ip", { data }).then(function (result) { + ajax("/admin/users/total-others-with-same-ip", { data }).then(function( + result + ) { self.set("totalOthersWithSameIP", result.total); }); - AdminUser.findAll("active", data).then(function (users) { + AdminUser.findAll("active", data).then(function(users) { self.setProperties({ other_accounts: users, - otherAccountsLoading: false, + otherAccountsLoading: false }); }); } }, - hide: function () { + hide: function() { this.set("show", false); }, deleteOtherAccounts: function() { var self = this; - bootbox.confirm(I18n.t("ip_lookup.confirm_delete_other_accounts"), I18n.t("no_value"), I18n.t("yes_value"), function (confirmed) { - if (confirmed) { - self.setProperties({ - other_accounts: null, - otherAccountsLoading: true, - totalOthersWithSameIP: null - }); + bootbox.confirm( + I18n.t("ip_lookup.confirm_delete_other_accounts"), + I18n.t("no_value"), + I18n.t("yes_value"), + function(confirmed) { + if (confirmed) { + self.setProperties({ + other_accounts: null, + otherAccountsLoading: true, + totalOthersWithSameIP: null + }); - ajax("/admin/users/delete-others-with-same-ip.json", { - type: "DELETE", - data: { - "ip": self.get("ip"), - "exclude": self.get("userId"), - "order": "trust_level DESC" - } - }).then(function() { - self.send("lookup"); - }); + ajax("/admin/users/delete-others-with-same-ip.json", { + type: "DELETE", + data: { + ip: self.get("ip"), + exclude: self.get("userId"), + order: "trust_level DESC" + } + }).then(function() { + self.send("lookup"); + }); + } } - }); + ); } } }); diff --git a/app/assets/javascripts/admin/components/moderation-history-item.js.es6 b/app/assets/javascripts/admin/components/moderation-history-item.js.es6 index b8674a8aafb..b7620b66cd3 100644 --- a/app/assets/javascripts/admin/components/moderation-history-item.js.es6 +++ b/app/assets/javascripts/admin/components/moderation-history-item.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: 'tr', + tagName: "tr" }); diff --git a/app/assets/javascripts/admin/components/penalty-post-action.js.es6 b/app/assets/javascripts/admin/components/penalty-post-action.js.es6 index d89c69a32d0..b4d82aba8b3 100644 --- a/app/assets/javascripts/admin/components/penalty-post-action.js.es6 +++ b/app/assets/javascripts/admin/components/penalty-post-action.js.es6 @@ -1,6 +1,6 @@ -import computed from 'ember-addons/ember-computed-decorators'; +import computed from "ember-addons/ember-computed-decorators"; -const ACTIONS = ['delete', 'edit', 'none']; +const ACTIONS = ["delete", "edit", "none"]; export default Ember.Component.extend({ postAction: null, postEdit: null, @@ -12,19 +12,19 @@ export default Ember.Component.extend({ }); }, - editing: Ember.computed.equal('postAction', 'edit'), + editing: Ember.computed.equal("postAction", "edit"), actions: { penaltyChanged() { - let postAction = this.get('postAction'); + let postAction = this.get("postAction"); // If we switch to edit mode, jump to the edit textarea - if (postAction === 'edit') { - Ember.run.scheduleOnce('afterRender', () => { + if (postAction === "edit") { + Ember.run.scheduleOnce("afterRender", () => { let $elem = this.$(); - let body = $elem.closest('.modal-body'); + let body = $elem.closest(".modal-body"); body.scrollTop(body.height()); - $elem.find('.post-editor').focus(); + $elem.find(".post-editor").focus(); }); } } diff --git a/app/assets/javascripts/admin/components/permalink-form.js.es6 b/app/assets/javascripts/admin/components/permalink-form.js.es6 index 90dcf2a7b20..969840a308f 100644 --- a/app/assets/javascripts/admin/components/permalink-form.js.es6 +++ b/app/assets/javascripts/admin/components/permalink-form.js.es6 @@ -1,45 +1,58 @@ -import Permalink from 'admin/models/permalink'; +import Permalink from "admin/models/permalink"; export default Ember.Component.extend({ - classNames: ['permalink-form'], + classNames: ["permalink-form"], formSubmitted: false, - permalinkType: 'topic_id', + permalinkType: "topic_id", permalinkTypes: function() { return [ - {id: 'topic_id', name: I18n.t('admin.permalink.topic_id')}, - {id: 'post_id', name: I18n.t('admin.permalink.post_id')}, - {id: 'category_id', name: I18n.t('admin.permalink.category_id')}, - {id: 'external_url', name: I18n.t('admin.permalink.external_url')} + { id: "topic_id", name: I18n.t("admin.permalink.topic_id") }, + { id: "post_id", name: I18n.t("admin.permalink.post_id") }, + { id: "category_id", name: I18n.t("admin.permalink.category_id") }, + { id: "external_url", name: I18n.t("admin.permalink.external_url") } ]; }.property(), permalinkTypePlaceholder: function() { - return 'admin.permalink.' + this.get('permalinkType'); - }.property('permalinkType'), + return "admin.permalink." + this.get("permalinkType"); + }.property("permalinkType"), actions: { submit: function() { - if (!this.get('formSubmitted')) { + if (!this.get("formSubmitted")) { const self = this; - self.set('formSubmitted', true); - const permalink = Permalink.create({url: self.get('url'), permalink_type: self.get('permalinkType'), permalink_type_value: self.get('permalink_type_value')}); - permalink.save().then(function(result) { - self.set('url', ''); - self.set('permalink_type_value', ''); - self.set('formSubmitted', false); - self.sendAction('action', Permalink.create(result.permalink)); - Em.run.schedule('afterRender', function() { self.$('.permalink-url').focus(); }); - }, function(e) { - self.set('formSubmitted', false); - let error; - if (e.responseJSON && e.responseJSON.errors) { - error = I18n.t("generic_error_with_reason", {error: e.responseJSON.errors.join('. ')}); - } else { - error = I18n.t("generic_error"); - } - bootbox.alert(error, function() { self.$('.permalink-url').focus(); }); + self.set("formSubmitted", true); + const permalink = Permalink.create({ + url: self.get("url"), + permalink_type: self.get("permalinkType"), + permalink_type_value: self.get("permalink_type_value") }); + permalink.save().then( + function(result) { + self.set("url", ""); + self.set("permalink_type_value", ""); + self.set("formSubmitted", false); + self.sendAction("action", Permalink.create(result.permalink)); + Em.run.schedule("afterRender", function() { + self.$(".permalink-url").focus(); + }); + }, + function(e) { + self.set("formSubmitted", false); + let error; + if (e.responseJSON && e.responseJSON.errors) { + error = I18n.t("generic_error_with_reason", { + error: e.responseJSON.errors.join(". ") + }); + } else { + error = I18n.t("generic_error"); + } + bootbox.alert(error, function() { + self.$(".permalink-url").focus(); + }); + } + ); } } }, @@ -47,10 +60,11 @@ export default Ember.Component.extend({ didInsertElement: function() { var self = this; self._super(); - Em.run.schedule('afterRender', function() { - self.$('.external-url').keydown(function(e) { - if (e.keyCode === 13) { // enter key - self.send('submit'); + Em.run.schedule("afterRender", function() { + self.$(".external-url").keydown(function(e) { + if (e.keyCode === 13) { + // enter key + self.send("submit"); } }); }); diff --git a/app/assets/javascripts/admin/components/resumable-upload.js.es6 b/app/assets/javascripts/admin/components/resumable-upload.js.es6 index 36f420d1009..4a8545b3ab6 100644 --- a/app/assets/javascripts/admin/components/resumable-upload.js.es6 +++ b/app/assets/javascripts/admin/components/resumable-upload.js.es6 @@ -1,5 +1,5 @@ -import { iconHTML } from 'discourse-common/lib/icon-library'; -import { bufferedRender } from 'discourse-common/lib/buffered-render'; +import { iconHTML } from "discourse-common/lib/icon-library"; +import { bufferedRender } from "discourse-common/lib/buffered-render"; /*global Resumable:true */ @@ -13,111 +13,119 @@ import { bufferedRender } from 'discourse-common/lib/buffered-render'; uploadText="UPLOAD" }} **/ -export default Ember.Component.extend(bufferedRender({ - tagName: "button", - classNames: ["btn", "ru"], - classNameBindings: ["isUploading"], - attributeBindings: ["translatedTitle:title"], +export default Ember.Component.extend( + bufferedRender({ + tagName: "button", + classNames: ["btn", "ru"], + classNameBindings: ["isUploading"], + attributeBindings: ["translatedTitle:title"], - resumable: null, + resumable: null, - isUploading: false, - progress: 0, + isUploading: false, + progress: 0, - rerenderTriggers: ['isUploading', 'progress'], + rerenderTriggers: ["isUploading", "progress"], - translatedTitle: function() { - const title = this.get('title'); - return title ? I18n.t(title) : this.get('text'); - }.property('title', 'text'), + translatedTitle: function() { + const title = this.get("title"); + return title ? I18n.t(title) : this.get("text"); + }.property("title", "text"), - text: function() { - if (this.get("isUploading")) { - return this.get("progress") + " %"; - } else { - return this.get("uploadText"); - } - }.property("isUploading", "progress"), + text: function() { + if (this.get("isUploading")) { + return this.get("progress") + " %"; + } else { + return this.get("uploadText"); + } + }.property("isUploading", "progress"), - buildBuffer(buffer) { - const icon = this.get("isUploading") ? "times" : "upload"; - buffer.push(iconHTML(icon)); - buffer.push("" + this.get("text") + ""); - buffer.push(""); - }, + buildBuffer(buffer) { + const icon = this.get("isUploading") ? "times" : "upload"; + buffer.push(iconHTML(icon)); + buffer.push("" + this.get("text") + ""); + buffer.push( + "" + ); + }, + + click: function() { + if (this.get("isUploading")) { + this.resumable.cancel(); + var self = this; + Em.run.later(function() { + self._reset(); + }); + return false; + } else { + return true; + } + }, + + _reset: function() { + this.setProperties({ isUploading: false, progress: 0 }); + }, + + _initialize: function() { + this.resumable = new Resumable({ + target: Discourse.getURL(this.get("target")), + maxFiles: 1, // only 1 file at a time + headers: { + "X-CSRF-Token": $("meta[name='csrf-token']").attr("content") + } + }); - click: function() { - if (this.get("isUploading")) { - this.resumable.cancel(); var self = this; - Em.run.later(function() { self._reset(); }); - return false; - } else { - return true; - } - }, - _reset: function() { - this.setProperties({ isUploading: false, progress: 0 }); - }, - - _initialize: function() { - this.resumable = new Resumable({ - target: Discourse.getURL(this.get("target")), - maxFiles: 1, // only 1 file at a time - headers: { "X-CSRF-Token": $("meta[name='csrf-token']").attr("content") } - }); - - var self = this; - - this.resumable.on("fileAdded", function() { - // automatically upload the selected file - self.resumable.upload(); - // mark as uploading - Em.run.later(function() { - self.set("isUploading", true); + this.resumable.on("fileAdded", function() { + // automatically upload the selected file + self.resumable.upload(); + // mark as uploading + Em.run.later(function() { + self.set("isUploading", true); + }); }); - }); - this.resumable.on("fileProgress", function(file) { - // update progress - Em.run.later(function() { - self.set("progress", parseInt(file.progress() * 100, 10)); + this.resumable.on("fileProgress", function(file) { + // update progress + Em.run.later(function() { + self.set("progress", parseInt(file.progress() * 100, 10)); + }); }); - }); - this.resumable.on("fileSuccess", function(file) { - Em.run.later(function() { - // mark as not uploading anymore - self._reset(); - // fire an event to allow the parent route to reload its model - self.sendAction("success", file.fileName); + this.resumable.on("fileSuccess", function(file) { + Em.run.later(function() { + // mark as not uploading anymore + self._reset(); + // fire an event to allow the parent route to reload its model + self.sendAction("success", file.fileName); + }); }); - }); - this.resumable.on("fileError", function(file, message) { - Em.run.later(function() { - // mark as not uploading anymore - self._reset(); - // fire an event to allow the parent route to display the error message - self.sendAction("error", file.fileName, message); + this.resumable.on("fileError", function(file, message) { + Em.run.later(function() { + // mark as not uploading anymore + self._reset(); + // fire an event to allow the parent route to display the error message + self.sendAction("error", file.fileName, message); + }); }); - }); + }.on("init"), - }.on("init"), + _assignBrowse: function() { + var self = this; + Em.run.schedule("afterRender", function() { + self.resumable.assignBrowse(self.$()); + }); + }.on("didInsertElement"), - _assignBrowse: function() { - var self = this; - Em.run.schedule("afterRender", function() { - self.resumable.assignBrowse(self.$()); - }); - }.on("didInsertElement"), - - _teardown: function() { - if (this.resumable) { - this.resumable.cancel(); - this.resumable = null; - } - }.on("willDestroyElement") - -})); + _teardown: function() { + if (this.resumable) { + this.resumable.cancel(); + this.resumable = null; + } + }.on("willDestroyElement") + }) +); diff --git a/app/assets/javascripts/admin/components/save-controls.js.es6 b/app/assets/javascripts/admin/components/save-controls.js.es6 index 414bbf3661f..51adbaf3c5f 100644 --- a/app/assets/javascripts/admin/components/save-controls.js.es6 +++ b/app/assets/javascripts/admin/components/save-controls.js.es6 @@ -1,13 +1,13 @@ -import computed from 'ember-addons/ember-computed-decorators'; +import computed from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - classNames: ['controls'], + classNames: ["controls"], - buttonDisabled: Ember.computed.or('model.isSaving', 'saveDisabled'), + buttonDisabled: Ember.computed.or("model.isSaving", "saveDisabled"), - @computed('model.isSaving') + @computed("model.isSaving") savingText(saving) { - return saving ? 'saving' : 'save'; + return saving ? "saving" : "save"; }, actions: { diff --git a/app/assets/javascripts/admin/components/screened-ip-address-form.js.es6 b/app/assets/javascripts/admin/components/screened-ip-address-form.js.es6 index ef6e7596d11..1a1dd977094 100644 --- a/app/assets/javascripts/admin/components/screened-ip-address-form.js.es6 +++ b/app/assets/javascripts/admin/components/screened-ip-address-form.js.es6 @@ -9,14 +9,14 @@ as an argument. **/ -import ScreenedIpAddress from 'admin/models/screened-ip-address'; -import computed from 'ember-addons/ember-computed-decorators'; -import { on } from 'ember-addons/ember-computed-decorators'; +import ScreenedIpAddress from "admin/models/screened-ip-address"; +import computed from "ember-addons/ember-computed-decorators"; +import { on } from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - classNames: ['screened-ip-address-form'], + classNames: ["screened-ip-address-form"], formSubmitted: false, - actionName: 'block', + actionName: "block", @computed adminWhitelistEnabled() { @@ -27,51 +27,71 @@ export default Ember.Component.extend({ actionNames(adminWhitelistEnabled) { if (adminWhitelistEnabled) { return [ - {id: 'block', name: I18n.t('admin.logs.screened_ips.actions.block')}, - {id: 'do_nothing', name: I18n.t('admin.logs.screened_ips.actions.do_nothing')}, - {id: 'allow_admin', name: I18n.t('admin.logs.screened_ips.actions.allow_admin')} + { id: "block", name: I18n.t("admin.logs.screened_ips.actions.block") }, + { + id: "do_nothing", + name: I18n.t("admin.logs.screened_ips.actions.do_nothing") + }, + { + id: "allow_admin", + name: I18n.t("admin.logs.screened_ips.actions.allow_admin") + } ]; } else { return [ - {id: 'block', name: I18n.t('admin.logs.screened_ips.actions.block')}, - {id: 'do_nothing', name: I18n.t('admin.logs.screened_ips.actions.do_nothing')} + { id: "block", name: I18n.t("admin.logs.screened_ips.actions.block") }, + { + id: "do_nothing", + name: I18n.t("admin.logs.screened_ips.actions.do_nothing") + } ]; } }, actions: { submit() { - if (!this.get('formSubmitted')) { - this.set('formSubmitted', true); + if (!this.get("formSubmitted")) { + this.set("formSubmitted", true); const screenedIpAddress = ScreenedIpAddress.create({ - ip_address: this.get('ip_address'), - action_name: this.get('actionName') - }); - screenedIpAddress.save().then(result => { - if (result.success) { - this.setProperties({ ip_address: '', formSubmitted: false }); - this.sendAction('action', ScreenedIpAddress.create(result.screened_ip_address)); - Ember.run.schedule('afterRender', () => this.$('.ip-address-input').focus()); - } else { - bootbox.alert(result.errors); - } - }).catch(e => { - this.set('formSubmitted', false); - const msg = (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) ? - I18n.t("generic_error_with_reason", {error: e.jqXHR.responseJSON.errors.join('. ')}) : - I18n.t("generic_error"); - bootbox.alert(msg, () => this.$('.ip-address-input').focus()); + ip_address: this.get("ip_address"), + action_name: this.get("actionName") }); + screenedIpAddress + .save() + .then(result => { + if (result.success) { + this.setProperties({ ip_address: "", formSubmitted: false }); + this.sendAction( + "action", + ScreenedIpAddress.create(result.screened_ip_address) + ); + Ember.run.schedule("afterRender", () => + this.$(".ip-address-input").focus() + ); + } else { + bootbox.alert(result.errors); + } + }) + .catch(e => { + this.set("formSubmitted", false); + const msg = + e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors + ? I18n.t("generic_error_with_reason", { + error: e.jqXHR.responseJSON.errors.join(". ") + }) + : I18n.t("generic_error"); + bootbox.alert(msg, () => this.$(".ip-address-input").focus()); + }); } } }, @on("didInsertElement") _init() { - Ember.run.schedule('afterRender', () => { - this.$('.ip-address-input').keydown(e => { + Ember.run.schedule("afterRender", () => { + this.$(".ip-address-input").keydown(e => { if (e.keyCode === 13) { - this.send('submit'); + this.send("submit"); } }); }); diff --git a/app/assets/javascripts/admin/components/silence-details.js.es6 b/app/assets/javascripts/admin/components/silence-details.js.es6 index 9250c1ae73b..91ad923ffcc 100644 --- a/app/assets/javascripts/admin/components/silence-details.js.es6 +++ b/app/assets/javascripts/admin/components/silence-details.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: '' + tagName: "" }); diff --git a/app/assets/javascripts/admin/components/site-setting.js.es6 b/app/assets/javascripts/admin/components/site-setting.js.es6 index 98bdf950f65..bd68c7d11ed 100644 --- a/app/assets/javascripts/admin/components/site-setting.js.es6 +++ b/app/assets/javascripts/admin/components/site-setting.js.es6 @@ -1,10 +1,10 @@ -import BufferedContent from 'discourse/mixins/buffered-content'; -import SiteSetting from 'admin/models/site-setting'; -import SettingComponent from 'admin/mixins/setting-component'; +import BufferedContent from "discourse/mixins/buffered-content"; +import SiteSetting from "admin/models/site-setting"; +import SettingComponent from "admin/mixins/setting-component"; export default Ember.Component.extend(BufferedContent, SettingComponent, { _save() { - const setting = this.get('buffered'); - return SiteSetting.update(setting.get('setting'), setting.get('value')); + const setting = this.get("buffered"); + return SiteSetting.update(setting.get("setting"), setting.get("value")); } }); diff --git a/app/assets/javascripts/admin/components/site-settings/bool.js.es6 b/app/assets/javascripts/admin/components/site-settings/bool.js.es6 index 6be1a14e27a..f46e9658327 100644 --- a/app/assets/javascripts/admin/components/site-settings/bool.js.es6 +++ b/app/assets/javascripts/admin/components/site-settings/bool.js.es6 @@ -1,17 +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; } + if (Ember.isEmpty(value)) { + return false; + } return value.toString() === "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 index 487239b78fa..36c712fa8df 100644 --- a/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 +++ b/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 @@ -1,7 +1,6 @@ import computed from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - @computed("value") selectedCategories: { get(value) { @@ -12,5 +11,4 @@ export default Ember.Component.extend({ return value; } } - }); diff --git a/app/assets/javascripts/admin/components/site-text-summary.js.es6 b/app/assets/javascripts/admin/components/site-text-summary.js.es6 index 642164f8710..0ebd139614e 100644 --- a/app/assets/javascripts/admin/components/site-text-summary.js.es6 +++ b/app/assets/javascripts/admin/components/site-text-summary.js.es6 @@ -1,25 +1,27 @@ -import { on } from 'ember-addons/ember-computed-decorators'; +import { on } from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - classNames: ['site-text'], - classNameBindings: ['siteText.overridden'], + classNames: ["site-text"], + classNameBindings: ["siteText.overridden"], - @on('didInsertElement') + @on("didInsertElement") highlightTerm() { - const term = this.get('term'); + const term = this.get("term"); if (term) { - this.$('.site-text-id, .site-text-value').highlight(term, {className: 'text-highlight'}); + this.$(".site-text-id, .site-text-value").highlight(term, { + className: "text-highlight" + }); } - this.$('.site-text-value').ellipsis(); + this.$(".site-text-value").ellipsis(); }, click() { - this.send('edit'); + this.send("edit"); }, actions: { edit() { - this.sendAction('editAction', this.get('siteText')); + this.sendAction("editAction", this.get("siteText")); } } }); diff --git a/app/assets/javascripts/admin/components/staff-actions.js.es6 b/app/assets/javascripts/admin/components/staff-actions.js.es6 index 9e742526afa..07764a80184 100644 --- a/app/assets/javascripts/admin/components/staff-actions.js.es6 +++ b/app/assets/javascripts/admin/components/staff-actions.js.es6 @@ -1,20 +1,20 @@ -import DiscourseURL from 'discourse/lib/url'; +import DiscourseURL from "discourse/lib/url"; export default Ember.Component.extend({ - classNames: ['table', 'staff-actions'], + classNames: ["table", "staff-actions"], willDestroyElement() { - this.$().off('click.discourse-staff-logs'); + this.$().off("click.discourse-staff-logs"); }, didInsertElement() { this._super(); - this.$().on('click.discourse-staff-logs', '[data-link-post-id]', e => { - let postId = $(e.target).attr('data-link-post-id'); + this.$().on("click.discourse-staff-logs", "[data-link-post-id]", e => { + let postId = $(e.target).attr("data-link-post-id"); - this.store.find('post', postId).then(p => { - DiscourseURL.routeTo(p.get('url')); + this.store.find("post", postId).then(p => { + DiscourseURL.routeTo(p.get("url")); }); return false; }); diff --git a/app/assets/javascripts/admin/components/suspension-details.js.es6 b/app/assets/javascripts/admin/components/suspension-details.js.es6 index 9250c1ae73b..91ad923ffcc 100644 --- a/app/assets/javascripts/admin/components/suspension-details.js.es6 +++ b/app/assets/javascripts/admin/components/suspension-details.js.es6 @@ -1,3 +1,3 @@ export default Ember.Component.extend({ - tagName: '' + tagName: "" }); diff --git a/app/assets/javascripts/admin/components/theme-setting.js.es6 b/app/assets/javascripts/admin/components/theme-setting.js.es6 index eb576e9b644..c95dd220db4 100644 --- a/app/assets/javascripts/admin/components/theme-setting.js.es6 +++ b/app/assets/javascripts/admin/components/theme-setting.js.es6 @@ -1,9 +1,12 @@ -import BufferedContent from 'discourse/mixins/buffered-content'; -import SettingComponent from 'admin/mixins/setting-component'; +import BufferedContent from "discourse/mixins/buffered-content"; +import SettingComponent from "admin/mixins/setting-component"; export default Ember.Component.extend(BufferedContent, SettingComponent, { - layoutName: 'admin/templates/components/site-setting', + layoutName: "admin/templates/components/site-setting", _save() { - return this.get('model').saveSettings(this.get('setting.setting'), this.get('buffered.value')); + return this.get("model").saveSettings( + this.get("setting.setting"), + this.get("buffered.value") + ); } }); diff --git a/app/assets/javascripts/admin/components/value-list.js.es6 b/app/assets/javascripts/admin/components/value-list.js.es6 index 3aa66ff1875..60e4a3cda73 100644 --- a/app/assets/javascripts/admin/components/value-list.js.es6 +++ b/app/assets/javascripts/admin/components/value-list.js.es6 @@ -1,5 +1,5 @@ export default Ember.Component.extend({ - classNameBindings: [':value-list'], + classNameBindings: [":value-list"], _enableSorting: function() { const self = this; @@ -10,16 +10,16 @@ export default Ember.Component.extend({ let over = null; let nodePlacement; - this.$().on('dragstart.discourse', '.values .value', function(e) { + this.$().on("dragstart.discourse", ".values .value", function(e) { dragging = e.currentTarget; - e.dataTransfer.effectAllowed = 'move'; + e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("text/html", e.currentTarget); }); - this.$().on('dragend.discourse', '.values .value', function() { + this.$().on("dragend.discourse", ".values .value", function() { Ember.run(function() { dragging.parentNode.removeChild(placeholder); - dragging.style.display = 'block'; + dragging.style.display = "block"; // Update data const from = Number(dragging.dataset.index); @@ -27,7 +27,7 @@ export default Ember.Component.extend({ if (from < to) to--; if (nodePlacement === "after") to++; - const collection = self.get('collection'); + const collection = self.get("collection"); const fromObj = collection.objectAt(from); collection.replace(from, 1); collection.replace(to, 0, [fromObj]); @@ -36,10 +36,12 @@ export default Ember.Component.extend({ return false; }); - this.$().on('dragover.discourse', '.values', function(e) { + this.$().on("dragover.discourse", ".values", function(e) { e.preventDefault(); - dragging.style.display = 'none'; - if (e.target.className === "placeholder") { return; } + dragging.style.display = "none"; + if (e.target.className === "placeholder") { + return; + } over = e.target; const relY = e.originalEvent.clientY - over.offsetTop; @@ -49,54 +51,61 @@ export default Ember.Component.extend({ if (relY > height) { nodePlacement = "after"; parent.insertBefore(placeholder, e.target.nextElementSibling); - } else if(relY < height) { + } else if (relY < height) { nodePlacement = "before"; parent.insertBefore(placeholder, e.target); } }); - }.on('didInsertElement'), + }.on("didInsertElement"), _removeSorting: function() { - this.$().off('dragover.discourse').off('dragend.discourse').off('dragstart.discourse'); - }.on('willDestroyElement'), + this.$() + .off("dragover.discourse") + .off("dragend.discourse") + .off("dragstart.discourse"); + }.on("willDestroyElement"), _setupCollection: function() { - const values = this.get('values'); - if (this.get('inputType') === "array") { - this.set('collection', values || []); + const values = this.get("values"); + if (this.get("inputType") === "array") { + this.set("collection", values || []); } else { - this.set('collection', (values && values.length) ? values.split("\n") : []); + this.set("collection", values && values.length ? values.split("\n") : []); } - }.on('init').observes('values'), + } + .on("init") + .observes("values"), _saveValues: function() { - if (this.get('inputType') === "array") { - this.set('values', this.get('collection')); + if (this.get("inputType") === "array") { + this.set("values", this.get("collection")); } else { - this.set('values', this.get('collection').join("\n")); + this.set("values", this.get("collection").join("\n")); } }, - inputInvalid: Ember.computed.empty('newValue'), + inputInvalid: Ember.computed.empty("newValue"), keyDown(e) { if (e.keyCode === 13) { - this.send('addValue'); + this.send("addValue"); } }, actions: { addValue() { - if (this.get('inputInvalid')) { return; } + if (this.get("inputInvalid")) { + return; + } - this.get('collection').addObject(this.get('newValue')); - this.set('newValue', ''); + this.get("collection").addObject(this.get("newValue")); + this.set("newValue", ""); this._saveValues(); }, removeValue(value) { - const collection = this.get('collection'); + const collection = this.get("collection"); collection.removeObject(value); this._saveValues(); } diff --git a/app/assets/javascripts/admin/components/watched-word-form.js.es6 b/app/assets/javascripts/admin/components/watched-word-form.js.es6 index e7ead641f2e..c9a61965e83 100644 --- a/app/assets/javascripts/admin/components/watched-word-form.js.es6 +++ b/app/assets/javascripts/admin/components/watched-word-form.js.es6 @@ -1,65 +1,94 @@ -import WatchedWord from 'admin/models/watched-word'; -import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators'; +import WatchedWord from "admin/models/watched-word"; +import { + default as computed, + on, + observes +} from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ - classNames: ['watched-word-form'], + classNames: ["watched-word-form"], formSubmitted: false, actionKey: null, showMessage: false, - @computed('regularExpressions') + @computed("regularExpressions") placeholderKey(regularExpressions) { - return "admin.watched_words.form.placeholder" + - (regularExpressions ? "_regexp" : ""); + return ( + "admin.watched_words.form.placeholder" + + (regularExpressions ? "_regexp" : "") + ); }, - @observes('word') + @observes("word") removeMessage() { - if (this.get('showMessage') && !Ember.isEmpty(this.get('word'))) { - this.set('showMessage', false); + if (this.get("showMessage") && !Ember.isEmpty(this.get("word"))) { + this.set("showMessage", false); } }, - @computed('word') + @computed("word") isUniqueWord(word) { const words = this.get("filteredContent") || []; - const filtered = words.filter(content => content.action === this.get("actionKey")); - return filtered.every(content => content.word.toLowerCase() !== word.toLowerCase()); + const filtered = words.filter( + content => content.action === this.get("actionKey") + ); + return filtered.every( + content => content.word.toLowerCase() !== word.toLowerCase() + ); }, actions: { submit() { if (!this.get("isUniqueWord")) { - this.setProperties({ showMessage: true, message: I18n.t('admin.watched_words.form.exists') }); + this.setProperties({ + showMessage: true, + message: I18n.t("admin.watched_words.form.exists") + }); return; } - if (!this.get('formSubmitted')) { - this.set('formSubmitted', true); + if (!this.get("formSubmitted")) { + this.set("formSubmitted", true); - const watchedWord = WatchedWord.create({ word: this.get('word'), action: this.get('actionKey') }); - - watchedWord.save().then(result => { - this.setProperties({ word: '', formSubmitted: false, showMessage: true, message: I18n.t('admin.watched_words.form.success') }); - this.sendAction('action', WatchedWord.create(result)); - Ember.run.schedule('afterRender', () => this.$('.watched-word-input').focus()); - }).catch(e => { - this.set('formSubmitted', false); - const msg = (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) ? - I18n.t("generic_error_with_reason", {error: e.jqXHR.responseJSON.errors.join('. ')}) : - I18n.t("generic_error"); - bootbox.alert(msg, () => this.$('.watched-word-input').focus()); + const watchedWord = WatchedWord.create({ + word: this.get("word"), + action: this.get("actionKey") }); + + watchedWord + .save() + .then(result => { + this.setProperties({ + word: "", + formSubmitted: false, + showMessage: true, + message: I18n.t("admin.watched_words.form.success") + }); + this.sendAction("action", WatchedWord.create(result)); + Ember.run.schedule("afterRender", () => + this.$(".watched-word-input").focus() + ); + }) + .catch(e => { + this.set("formSubmitted", false); + const msg = + e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors + ? I18n.t("generic_error_with_reason", { + error: e.jqXHR.responseJSON.errors.join(". ") + }) + : I18n.t("generic_error"); + bootbox.alert(msg, () => this.$(".watched-word-input").focus()); + }); } } }, @on("didInsertElement") _init() { - Ember.run.schedule('afterRender', () => { - this.$('.watched-word-input').keydown(e => { + Ember.run.schedule("afterRender", () => { + this.$(".watched-word-input").keydown(e => { if (e.keyCode === 13) { - this.send('submit'); + this.send("submit"); } }); }); diff --git a/app/assets/javascripts/admin/components/watched-word-uploader.js.es6 b/app/assets/javascripts/admin/components/watched-word-uploader.js.es6 index 8d9e6ba0a97..e5ff9a1fd77 100644 --- a/app/assets/javascripts/admin/components/watched-word-uploader.js.es6 +++ b/app/assets/javascripts/admin/components/watched-word-uploader.js.es6 @@ -2,16 +2,16 @@ import computed from "ember-addons/ember-computed-decorators"; import UploadMixin from "discourse/mixins/upload"; export default Em.Component.extend(UploadMixin, { - type: 'csv', - classNames: 'watched-words-uploader', - uploadUrl: '/admin/logs/watched_words/upload', + type: "csv", + classNames: "watched-words-uploader", + uploadUrl: "/admin/logs/watched_words/upload", addDisabled: Em.computed.alias("uploading"), validateUploadedFilesOptions() { return { csvOnly: true }; }, - @computed('actionKey') + @computed("actionKey") data(actionKey) { return { action_key: actionKey }; }, diff --git a/app/assets/javascripts/admin/controllers/admin-api-keys.js.es6 b/app/assets/javascripts/admin/controllers/admin-api-keys.js.es6 index 529538263c8..69a1c321f78 100644 --- a/app/assets/javascripts/admin/controllers/admin-api-keys.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-api-keys.js.es6 @@ -1,32 +1,40 @@ -import ApiKey from 'admin/models/api-key'; +import ApiKey from "admin/models/api-key"; export default Ember.Controller.extend({ - actions: { generateMasterKey() { - ApiKey.generateMasterKey().then(key => this.get('model').pushObject(key)); + ApiKey.generateMasterKey().then(key => this.get("model").pushObject(key)); }, regenerateKey(key) { - bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), result => { - if (result) { - key.regenerate(); + bootbox.confirm( + I18n.t("admin.api.confirm_regen"), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + key.regenerate(); + } } - }); + ); }, revokeKey(key) { - bootbox.confirm(I18n.t("admin.api.confirm_revoke"), I18n.t("no_value"), I18n.t("yes_value"), result => { - if (result) { - key.revoke().then(() => this.get('model').removeObject(key)); + bootbox.confirm( + I18n.t("admin.api.confirm_revoke"), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + key.revoke().then(() => this.get("model").removeObject(key)); + } } - }); + ); } }, // Has a master key already been generated? hasMasterKey: function() { - return !!this.get('model').findBy('user', null); - }.property('model.[]') - + return !!this.get("model").findBy("user", null); + }.property("model.[]") }); 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 67b6c58d061..49e8d9d4412 100644 --- a/app/assets/javascripts/admin/controllers/admin-backups-index.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-backups-index.js.es6 @@ -1,13 +1,15 @@ -import { ajax } from 'discourse/lib/ajax'; +import { ajax } from "discourse/lib/ajax"; export default Ember.Controller.extend({ adminBackups: Ember.inject.controller(), - status: Ember.computed.alias('adminBackups.model'), + status: Ember.computed.alias("adminBackups.model"), - uploadLabel: function() { return I18n.t("admin.backups.upload.label"); }.property(), + uploadLabel: function() { + return I18n.t("admin.backups.upload.label"); + }.property(), restoreTitle: function() { - if (!this.get('status.allowRestore')) { + if (!this.get("status.allowRestore")) { return "admin.backups.operations.restore.is_disabled"; } else if (this.get("status.isOperationRunning")) { return "admin.backups.operations.is_running"; @@ -17,7 +19,6 @@ export default Ember.Controller.extend({ }.property("status.{allowRestore,isOperationRunning}"), actions: { - toggleReadOnlyMode() { var self = this; if (!this.site.get("isReadOnly")) { @@ -38,9 +39,8 @@ export default Ember.Controller.extend({ }, download(backup) { - let link = backup.get('filename'); - ajax("/admin/backups/" + link, { type: "PUT" }) - .then(() => { + let link = backup.get("filename"); + ajax("/admin/backups/" + link, { type: "PUT" }).then(() => { bootbox.alert(I18n.t("admin.backups.operations.download.alert")); }); } diff --git a/app/assets/javascripts/admin/controllers/admin-backups.js.es6 b/app/assets/javascripts/admin/controllers/admin-backups.js.es6 index a429883378e..5cfa57271eb 100644 --- a/app/assets/javascripts/admin/controllers/admin-backups.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-backups.js.es6 @@ -1,5 +1,9 @@ export default Ember.Controller.extend({ noOperationIsRunning: Ember.computed.not("model.isOperationRunning"), - rollbackEnabled: Ember.computed.and("model.canRollback", "model.restoreEnabled", "noOperationIsRunning"), + 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 7ddc6f3ac4e..c0d58e3b114 100644 --- a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 @@ -1,108 +1,139 @@ -import { popupAjaxError } from 'discourse/lib/ajax-error'; -import BufferedContent from 'discourse/mixins/buffered-content'; -import { propertyNotEqual } from 'discourse/lib/computed'; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import BufferedContent from "discourse/mixins/buffered-content"; +import { propertyNotEqual } from "discourse/lib/computed"; export default Ember.Controller.extend(BufferedContent, { adminBadges: Ember.inject.controller(), saving: false, - savingStatus: '', + savingStatus: "", - badgeTypes: Ember.computed.alias('adminBadges.badgeTypes'), - badgeGroupings: Ember.computed.alias('adminBadges.badgeGroupings'), - badgeTriggers: Ember.computed.alias('adminBadges.badgeTriggers'), - protectedSystemFields: Ember.computed.alias('adminBadges.protectedSystemFields'), + badgeTypes: Ember.computed.alias("adminBadges.badgeTypes"), + badgeGroupings: Ember.computed.alias("adminBadges.badgeGroupings"), + badgeTriggers: Ember.computed.alias("adminBadges.badgeTriggers"), + protectedSystemFields: Ember.computed.alias( + "adminBadges.protectedSystemFields" + ), - readOnly: Ember.computed.alias('buffered.system'), - showDisplayName: propertyNotEqual('name', 'displayName'), + readOnly: Ember.computed.alias("buffered.system"), + showDisplayName: propertyNotEqual("name", "displayName"), hasQuery: function() { - const bQuery = this.get('buffered.query'); + const bQuery = this.get("buffered.query"); if (bQuery) { return bQuery.trim().length > 0; } - const mQuery = this.get('model.query'); + const mQuery = this.get("model.query"); return mQuery && mQuery.trim().length > 0; - }.property('model.query', 'buffered.query'), + }.property("model.query", "buffered.query"), _resetSaving: function() { - this.set('saving', false); - this.set('savingStatus', ''); - }.observes('model.id'), + this.set("saving", false); + this.set("savingStatus", ""); + }.observes("model.id"), actions: { save() { - if (!this.get('saving')) { - let fields = ['allow_title', 'multiple_grant', - 'listable', 'auto_revoke', - 'enabled', 'show_posts', - 'target_posts', 'name', 'description', - 'long_description', - 'icon', 'image', 'query', 'badge_grouping_id', - 'trigger', 'badge_type_id']; + if (!this.get("saving")) { + let fields = [ + "allow_title", + "multiple_grant", + "listable", + "auto_revoke", + "enabled", + "show_posts", + "target_posts", + "name", + "description", + "long_description", + "icon", + "image", + "query", + "badge_grouping_id", + "trigger", + "badge_type_id" + ]; - if (this.get('buffered.system')){ - var protectedFields = this.get('protectedSystemFields'); - fields = _.filter(fields, function(f){ - return !_.include(protectedFields,f); + if (this.get("buffered.system")) { + var protectedFields = this.get("protectedSystemFields"); + fields = _.filter(fields, function(f) { + return !_.include(protectedFields, f); }); } - this.set('saving', true); - this.set('savingStatus', I18n.t('saving')); + this.set("saving", true); + this.set("savingStatus", I18n.t("saving")); - const boolFields = ['allow_title', 'multiple_grant', - 'listable', 'auto_revoke', - 'enabled', 'show_posts', - 'target_posts' ]; + const boolFields = [ + "allow_title", + "multiple_grant", + "listable", + "auto_revoke", + "enabled", + "show_posts", + "target_posts" + ]; const data = {}; - const buffered = this.get('buffered'); - fields.forEach(function(field){ + const buffered = this.get("buffered"); + fields.forEach(function(field) { var d = buffered.get(field); - if (_.include(boolFields, field)) { d = !!d; } + if (_.include(boolFields, field)) { + d = !!d; + } data[field] = d; }); - const newBadge = !this.get('id'); - const model = this.get('model'); - this.get('model').save(data).then(() => { - if (newBadge) { - const adminBadges = this.get('adminBadges.model'); - if (!adminBadges.includes(model)) { - adminBadges.pushObject(model); + const newBadge = !this.get("id"); + const model = this.get("model"); + this.get("model") + .save(data) + .then(() => { + if (newBadge) { + const adminBadges = this.get("adminBadges.model"); + if (!adminBadges.includes(model)) { + adminBadges.pushObject(model); + } + this.transitionToRoute("adminBadges.show", model.get("id")); + } else { + this.commitBuffer(); + this.set("savingStatus", I18n.t("saved")); } - this.transitionToRoute('adminBadges.show', model.get('id')); - } else { - this.commitBuffer(); - this.set('savingStatus', I18n.t('saved')); - } - - }).catch(popupAjaxError).finally(() => { - this.set('saving', false); - this.set('savingStatus', ''); - }); + }) + .catch(popupAjaxError) + .finally(() => { + this.set("saving", false); + this.set("savingStatus", ""); + }); } }, destroy() { - const adminBadges = this.get('adminBadges.model'); - const model = this.get('model'); + const adminBadges = this.get("adminBadges.model"); + const model = this.get("model"); - if (!model.get('id')) { - this.transitionToRoute('adminBadges.index'); + if (!model.get("id")) { + this.transitionToRoute("adminBadges.index"); return; } - return bootbox.confirm(I18n.t("admin.badges.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => { - if (result) { - model.destroy().then(() => { - adminBadges.removeObject(model); - this.transitionToRoute('adminBadges.index'); - }).catch(() => { - bootbox.alert(I18n.t('generic_error')); - }); + return bootbox.confirm( + I18n.t("admin.badges.delete_confirm"), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + model + .destroy() + .then(() => { + adminBadges.removeObject(model); + this.transitionToRoute("adminBadges.index"); + }) + .catch(() => { + bootbox.alert(I18n.t("generic_error")); + }); + } } - }); + ); } } }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-colors-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-colors-show.js.es6 index e333d2a58de..ca62835a04c 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-colors-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-colors-show.js.es6 @@ -1,7 +1,7 @@ -import computed from 'ember-addons/ember-computed-decorators'; +import computed from "ember-addons/ember-computed-decorators"; export default Ember.Controller.extend({ - @computed("model.colors","onlyOverridden") + @computed("model.colors", "onlyOverridden") colors(allColors, onlyOverridden) { if (onlyOverridden) { return allColors.filter(color => color.get("overridden")); @@ -11,7 +11,6 @@ export default Ember.Controller.extend({ }, actions: { - revert: function(color) { color.revert(); }, @@ -28,14 +27,20 @@ export default Ember.Controller.extend({ let range = document.createRange(); range.selectNode(area[0]); window.getSelection().addRange(range); - let successful = document.execCommand('copy'); + let successful = document.execCommand("copy"); if (successful) { - this.set("model.savingStatus", I18n.t("admin.customize.copied_to_clipboard")); + this.set( + "model.savingStatus", + I18n.t("admin.customize.copied_to_clipboard") + ); } else { - this.set("model.savingStatus", I18n.t("admin.customize.copy_to_clipboard_error")); + this.set( + "model.savingStatus", + I18n.t("admin.customize.copy_to_clipboard_error") + ); } - setTimeout(()=>{ + setTimeout(() => { this.set("model.savingStatus", null); }, 2000); @@ -46,29 +51,38 @@ export default Ember.Controller.extend({ }, copy() { - var newColorScheme = Em.copy(this.get('model'), true); - newColorScheme.set('name', I18n.t('admin.customize.colors.copy_name_prefix') + ' ' + this.get('model.name')); - newColorScheme.save().then(()=>{ - this.get('allColors').pushObject(newColorScheme); - this.replaceRoute('adminCustomize.colors.show', newColorScheme); + var newColorScheme = Em.copy(this.get("model"), true); + newColorScheme.set( + "name", + I18n.t("admin.customize.colors.copy_name_prefix") + + " " + + this.get("model.name") + ); + newColorScheme.save().then(() => { + this.get("allColors").pushObject(newColorScheme); + this.replaceRoute("adminCustomize.colors.show", newColorScheme); }); }, save: function() { - this.get('model').save(); + this.get("model").save(); }, destroy: function() { - - const model = this.get('model'); - return bootbox.confirm(I18n.t("admin.customize.colors.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => { - if (result) { - model.destroy().then(()=>{ - this.get('allColors').removeObject(model); - this.replaceRoute('adminCustomize.colors'); - }); + const model = this.get("model"); + return bootbox.confirm( + I18n.t("admin.customize.colors.delete_confirm"), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + model.destroy().then(() => { + this.get("allColors").removeObject(model); + this.replaceRoute("adminCustomize.colors"); + }); + } } - }); + ); } } }); 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 87166e386f5..945a46acf36 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6 @@ -1,41 +1,43 @@ -import showModal from 'discourse/lib/show-modal'; +import showModal from "discourse/lib/show-modal"; export default Ember.Controller.extend({ baseColorScheme: function() { - return this.get('model').findBy('is_base', true); - }.property('model.@each.id'), + return this.get("model").findBy("is_base", true); + }.property("model.@each.id"), baseColorSchemes: function() { - return this.get('model').filterBy('is_base', true); - }.property('model.@each.id'), + return this.get("model").filterBy("is_base", true); + }.property("model.@each.id"), baseColors: function() { var baseColorsHash = Em.Object.create({}); - _.each(this.get('baseColorScheme.colors'), function(color){ - baseColorsHash.set(color.get('name'), color); + _.each(this.get("baseColorScheme.colors"), function(color) { + baseColorsHash.set(color.get("name"), color); }); return baseColorsHash; - }.property('baseColorScheme'), + }.property("baseColorScheme"), actions: { - newColorSchemeWithBase(baseKey) { - const base = this.get('baseColorSchemes').findBy('base_scheme_id', baseKey); + const base = this.get("baseColorSchemes").findBy( + "base_scheme_id", + baseKey + ); const newColorScheme = Em.copy(base, true); - newColorScheme.set('name', I18n.t('admin.customize.colors.new_name')); - newColorScheme.set('base_scheme_id', base.get('base_scheme_id')); - newColorScheme.save().then(()=>{ - this.get('model').pushObject(newColorScheme); - newColorScheme.set('savingStatus', null); - this.replaceRoute('adminCustomize.colors.show', newColorScheme); + newColorScheme.set("name", I18n.t("admin.customize.colors.new_name")); + newColorScheme.set("base_scheme_id", base.get("base_scheme_id")); + newColorScheme.save().then(() => { + this.get("model").pushObject(newColorScheme); + newColorScheme.set("savingStatus", null); + this.replaceRoute("adminCustomize.colors.show", newColorScheme); }); }, newColorScheme() { - showModal('admin-color-scheme-select-base', { model: this.get('baseColorSchemes'), admin: true}); - }, - - + showModal("admin-color-scheme-select-base", { + model: this.get("baseColorSchemes"), + admin: true + }); + } } - }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 index 4c5a2a28549..5a20a94cbfb 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 @@ -1,38 +1,47 @@ -import { popupAjaxError } from 'discourse/lib/ajax-error'; -import { bufferedProperty } from 'discourse/mixins/buffered-content'; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { bufferedProperty } from "discourse/mixins/buffered-content"; -export default Ember.Controller.extend(bufferedProperty('emailTemplate'), { +export default Ember.Controller.extend(bufferedProperty("emailTemplate"), { saved: false, hasMultipleSubjects: function() { - const buffered = this.get('buffered'); - if (buffered.getProperties('subject')['subject']) { + const buffered = this.get("buffered"); + if (buffered.getProperties("subject")["subject"]) { return false; } else { - return buffered.getProperties('id')['id']; + return buffered.getProperties("id")["id"]; } }.property("buffered"), actions: { saveChanges() { - this.set('saved', false); - const buffered = this.get('buffered'); - this.get('emailTemplate').save(buffered.getProperties('subject', 'body')).then(() => { - this.set('saved', true); - }).catch(popupAjaxError); + this.set("saved", false); + const buffered = this.get("buffered"); + this.get("emailTemplate") + .save(buffered.getProperties("subject", "body")) + .then(() => { + this.set("saved", true); + }) + .catch(popupAjaxError); }, revertChanges() { - this.set('saved', false); - bootbox.confirm(I18n.t('admin.customize.email_templates.revert_confirm'), result => { - if (result) { - this.get('emailTemplate').revert().then(props => { - const buffered = this.get('buffered'); - buffered.setProperties(props); - this.commitBuffer(); - }).catch(popupAjaxError); + this.set("saved", false); + bootbox.confirm( + I18n.t("admin.customize.email_templates.revert_confirm"), + result => { + if (result) { + this.get("emailTemplate") + .revert() + .then(props => { + const buffered = this.get("buffered"); + buffered.setProperties(props); + this.commitBuffer(); + }) + .catch(popupAjaxError); + } } - }); + ); } } }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-email-templates.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-email-templates.js.es6 index fe9cd69804c..6fe215c9c3e 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-email-templates.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-email-templates.js.es6 @@ -1,6 +1,6 @@ export default Ember.Controller.extend({ - titleSorting: ['title'], + titleSorting: ["title"], emailTemplates: null, - sortedTemplates: Ember.computed.sort('emailTemplates', 'titleSorting') + sortedTemplates: Ember.computed.sort("emailTemplates", "titleSorting") }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 index 28ae718afab..33b46886dbe 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-themes-edit.js.es6 @@ -1,66 +1,91 @@ -import { url } from 'discourse/lib/computed'; -import { default as computed, observes } from 'ember-addons/ember-computed-decorators'; +import { url } from "discourse/lib/computed"; +import { + default as computed, + observes +} from "ember-addons/ember-computed-decorators"; export default Ember.Controller.extend({ maximized: false, section: null, - editRouteName: 'adminCustomizeThemes.edit', + editRouteName: "adminCustomizeThemes.edit", targets: [ - { id: 0, name: 'common' }, - { id: 1, name: 'desktop' }, - { id: 2, name: 'mobile' }, - { id: 3, name: 'settings' } + { id: 0, name: "common" }, + { id: 1, name: "desktop" }, + { id: 2, name: "mobile" }, + { id: 3, name: "settings" } ], - fieldsForTarget: function (target) { - const common = ["scss", "head_tag", "header", "after_header", "body_tag", "footer"]; - switch(target) { - case "common": return [...common, "embedded_scss"]; - case "desktop": return common; - case "mobile": return common; - case "settings": return ["yaml"]; + fieldsForTarget: function(target) { + const common = [ + "scss", + "head_tag", + "header", + "after_header", + "body_tag", + "footer" + ]; + switch (target) { + case "common": + return [...common, "embedded_scss"]; + case "desktop": + return common; + case "mobile": + return common; + case "settings": + return ["yaml"]; } }, - @computed('onlyOverridden') + @computed("onlyOverridden") showCommon() { - return this.shouldShow('common'); + return this.shouldShow("common"); }, - @computed('onlyOverridden') + @computed("onlyOverridden") showDesktop() { - return this.shouldShow('desktop'); + return this.shouldShow("desktop"); }, - @computed('onlyOverridden') + @computed("onlyOverridden") showMobile() { - return this.shouldShow('mobile'); + return this.shouldShow("mobile"); }, - @computed('onlyOverridden', 'model.remote_theme') + @computed("onlyOverridden", "model.remote_theme") showSettings() { return false; }, - @observes('onlyOverridden') + @observes("onlyOverridden") onlyOverriddenChanged() { - if (this.get('onlyOverridden')) { - if (!this.get('model').hasEdited(this.get('currentTargetName'), this.get('fieldName'))) { - let target = (this.get('showCommon') && 'common') || - (this.get('showDesktop') && 'desktop') || - (this.get('showMobile') && 'mobile'); + if (this.get("onlyOverridden")) { + if ( + !this.get("model").hasEdited( + this.get("currentTargetName"), + this.get("fieldName") + ) + ) { + let target = + (this.get("showCommon") && "common") || + (this.get("showDesktop") && "desktop") || + (this.get("showMobile") && "mobile"); - let fields = this.get('model.theme_fields'); - let field = fields && fields.find(f => (f.target === target)); - this.replaceRoute(this.get('editRouteName'), this.get('model.id'), target, field && field.name); + let fields = this.get("model.theme_fields"); + let field = fields && fields.find(f => f.target === target); + this.replaceRoute( + this.get("editRouteName"), + this.get("model.id"), + target, + field && field.name + ); } } }, - shouldShow(target){ - if(!this.get("onlyOverridden")) { + shouldShow(target) { + if (!this.get("onlyOverridden")) { return true; } return this.get("model").hasEdited(target); @@ -69,13 +94,13 @@ export default Ember.Controller.extend({ currentTarget: 0, setTargetName: function(name) { - const target = this.get('targets').find(t => t.name === name); + const target = this.get("targets").find(t => t.name === name); this.set("currentTarget", target && target.id); }, @computed("currentTarget") currentTargetName(id) { - const target = this.get('targets').find(t => t.id === parseInt(id, 10)); + const target = this.get("targets").find(t => t.id === parseInt(id, 10)); return target && target.name; }, @@ -87,7 +112,7 @@ export default Ember.Controller.extend({ @computed("currentTargetName", "fieldName", "saving") error(target, fieldName) { - return this.get('model').getError(target, fieldName); + return this.get("model").getError(target, fieldName); }, @computed("fieldName", "currentTargetName") @@ -116,9 +141,9 @@ export default Ember.Controller.extend({ fields = fields.filter(name => model.hasEdited(targetName, name)); } - return fields.map(name=>{ + return fields.map(name => { let hash = { - key: (`admin.customize.theme.${name}.text`), + key: `admin.customize.theme.${name}.text`, name: name }; @@ -132,30 +157,36 @@ export default Ember.Controller.extend({ }); }, - previewUrl: url('model.id', '/admin/themes/%@/preview'), + previewUrl: url("model.id", "/admin/themes/%@/preview"), maximizeIcon: function() { - return this.get('maximized') ? 'compress' : 'expand'; - }.property('maximized'), + 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'), + 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'), + return !this.get("model.changed") || this.get("model.isSaving"); + }.property("model.changed", "model.isSaving"), actions: { save() { - this.set('saving', true); - this.get('model').saveChanges("theme_fields").finally(()=>{this.set('saving', false);}); + this.set("saving", true); + this.get("model") + .saveChanges("theme_fields") + .finally(() => { + this.set("saving", false); + }); }, toggleMaximize: function() { - this.toggleProperty('maximized'); - Em.run.next(()=>{ - this.appEvents.trigger('ace:resize'); + this.toggleProperty("maximized"); + Em.run.next(() => { + this.appEvents.trigger("ace:resize"); }); } } diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 index 16eff829470..20a16ab6269 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 @@ -1,63 +1,72 @@ -import { default as computed } from 'ember-addons/ember-computed-decorators'; -import { url } from 'discourse/lib/computed'; -import { popupAjaxError } from 'discourse/lib/ajax-error'; -import showModal from 'discourse/lib/show-modal'; -import ThemeSettings from 'admin/models/theme-settings'; +import { default as computed } from "ember-addons/ember-computed-decorators"; +import { url } from "discourse/lib/computed"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import showModal from "discourse/lib/show-modal"; +import ThemeSettings from "admin/models/theme-settings"; const THEME_UPLOAD_VAR = 2; export default Ember.Controller.extend({ - - editRouteName: 'adminCustomizeThemes.edit', + editRouteName: "adminCustomizeThemes.edit", @computed("model", "allThemes") parentThemes(model, allThemes) { let parents = allThemes.filter(theme => - _.contains(theme.get("childThemes"), model)); + _.contains(theme.get("childThemes"), model) + ); return parents.length === 0 ? null : parents; }, @computed("model.theme_fields.@each") hasEditedFields(fields) { - return fields.any(f=>!Em.isBlank(f.value)); + return fields.any(f => !Em.isBlank(f.value)); }, - @computed('model.theme_fields.@each') + @computed("model.theme_fields.@each") editedDescriptions(fields) { let descriptions = []; let description = target => { - let current = fields.filter(field => field.target === target && !Em.isBlank(field.value)); + let current = fields.filter( + field => field.target === target && !Em.isBlank(field.value) + ); if (current.length > 0) { - let text = I18n.t('admin.customize.theme.'+target); - let localized = current.map(f=>I18n.t('admin.customize.theme.'+f.name + '.text')); + let text = I18n.t("admin.customize.theme." + target); + let localized = current.map(f => + I18n.t("admin.customize.theme." + f.name + ".text") + ); return text + ": " + localized.join(" , "); } }; - ['common', 'desktop', 'mobile'].forEach(target => { + ["common", "desktop", "mobile"].forEach(target => { descriptions.push(description(target)); }); - return descriptions.reject(d=>Em.isBlank(d)); + return descriptions.reject(d => Em.isBlank(d)); }, - previewUrl: url('model.id', '/admin/themes/%@/preview'), + previewUrl: url("model.id", "/admin/themes/%@/preview"), @computed("colorSchemeId", "model.color_scheme_id") colorSchemeChanged(colorSchemeId, existingId) { colorSchemeId = colorSchemeId === null ? null : parseInt(colorSchemeId); - return colorSchemeId !== existingId; + return colorSchemeId !== existingId; }, - @computed("availableChildThemes", "model.childThemes.@each", "model", "allowChildThemes") + @computed( + "availableChildThemes", + "model.childThemes.@each", + "model", + "allowChildThemes" + ) selectableChildThemes(available, childThemes, model, allowChildThemes) { if (!allowChildThemes && (!childThemes || childThemes.length === 0)) { return null; } let themes = []; - available.forEach(t=> { - if (!childThemes || (childThemes.indexOf(t) === -1)) { + available.forEach(t => { + if (!childThemes || childThemes.indexOf(t) === -1) { themes.push(t); - }; + } }); return themes.length === 0 ? null : themes; }, @@ -90,44 +99,48 @@ export default Ember.Controller.extend({ return settings.length > 0; }, - downloadUrl: url('model.id', '/admin/themes/%@'), + downloadUrl: url("model.id", "/admin/themes/%@"), actions: { - updateToLatest() { this.set("updatingRemote", true); - this.get("model").updateToLatest() + this.get("model") + .updateToLatest() .catch(popupAjaxError) - .finally(()=>{ + .finally(() => { this.set("updatingRemote", false); }); }, checkForThemeUpdates() { this.set("updatingRemote", true); - this.get("model").checkForUpdates() + this.get("model") + .checkForUpdates() .catch(popupAjaxError) - .finally(()=>{ + .finally(() => { this.set("updatingRemote", false); }); }, addUploadModal() { - showModal('admin-add-upload', {admin: true, name: ''}); + showModal("admin-add-upload", { admin: true, name: "" }); }, addUpload(info) { let model = this.get("model"); - model.setField('common', info.name, '', info.upload_id, THEME_UPLOAD_VAR); - model.saveChanges('theme_fields').catch(e => popupAjaxError(e)); + model.setField("common", info.name, "", info.upload_id, THEME_UPLOAD_VAR); + model.saveChanges("theme_fields").catch(e => popupAjaxError(e)); }, cancelChangeScheme() { this.set("colorSchemeId", this.get("model.color_scheme_id")); }, - changeScheme(){ + changeScheme() { let schemeId = this.get("colorSchemeId"); - this.set("model.color_scheme_id", schemeId === null ? null : parseInt(schemeId)); + this.set( + "model.color_scheme_id", + schemeId === null ? null : parseInt(schemeId) + ); this.get("model").saveChanges("color_scheme_id"); }, startEditingName() { @@ -144,14 +157,23 @@ export default Ember.Controller.extend({ }, editTheme() { - let edit = ()=>this.transitionToRoute(this.get('editRouteName'), this.get('model.id'), 'common', 'scss'); + let edit = () => + this.transitionToRoute( + this.get("editRouteName"), + this.get("model.id"), + "common", + "scss" + ); if (this.get("model.remote_theme")) { - bootbox.confirm(I18n.t("admin.customize.theme.edit_confirm"), result => { - if (result) { - edit(); - } - }); + bootbox.confirm( + I18n.t("admin.customize.theme.edit_confirm"), + result => { + if (result) { + edit(); + } + } + ); } else { edit(); } @@ -159,10 +181,10 @@ export default Ember.Controller.extend({ applyDefault() { const model = this.get("model"); - model.saveChanges("default").then(()=>{ + model.saveChanges("default").then(() => { if (model.get("default")) { - this.get("allThemes").forEach(theme=>{ - if (theme !== model && theme.get('default')) { + this.get("allThemes").forEach(theme => { + if (theme !== model && theme.get("default")) { theme.set("default", false); } }); @@ -182,13 +204,15 @@ export default Ember.Controller.extend({ removeUpload(upload) { return bootbox.confirm( - I18n.t("admin.customize.theme.delete_upload_confirm"), - I18n.t("no_value"), - I18n.t("yes_value"), result => { - if (result) { - this.get("model").removeField(upload); - } - }); + I18n.t("admin.customize.theme.delete_upload_confirm"), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + this.get("model").removeField(upload); + } + } + ); }, removeChildTheme(theme) { @@ -196,17 +220,20 @@ export default Ember.Controller.extend({ }, destroy() { - return bootbox.confirm(I18n.t("admin.customize.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => { - if (result) { - const model = this.get('model'); - model.destroyRecord().then(() => { - this.get('allThemes').removeObject(model); - this.transitionToRoute('adminCustomizeThemes'); - }); + return bootbox.confirm( + I18n.t("admin.customize.delete_confirm"), + I18n.t("no_value"), + I18n.t("yes_value"), + result => { + if (result) { + const model = this.get("model"); + model.destroyRecord().then(() => { + this.get("allThemes").removeObject(model); + this.transitionToRoute("adminCustomizeThemes"); + }); + } } - }); - }, - + ); + } } - }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 index b9a897a26a1..ecd80018955 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6 @@ -1,10 +1,14 @@ -import { default as computed } from 'ember-addons/ember-computed-decorators'; +import { default as computed } from "ember-addons/ember-computed-decorators"; export default Ember.Controller.extend({ - @computed('model', 'model.@each') + @computed("model", "model.@each") sortedThemes(themes) { return _.sortBy(themes.content, t => { - return [!t.get("default"), !t.get("user_selectable"), t.get("name").toLowerCase()]; + return [ + !t.get("default"), + !t.get("user_selectable"), + t.get("name").toLowerCase() + ]; }); } }); diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6 index f65e2f04fdc..4ba338f5ad3 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-dashboard-next.js.es6 @@ -26,31 +26,46 @@ export default Ember.Controller.extend({ fetchDashboard() { if (this.get("isLoading")) return; - if (!this.get("dashboardFetchedAt") || moment().subtract(30, "minutes").toDate() > this.get("dashboardFetchedAt")) { + if ( + !this.get("dashboardFetchedAt") || + moment() + .subtract(30, "minutes") + .toDate() > this.get("dashboardFetchedAt") + ) { this.set("isLoading", true); const versionChecks = this.siteSettings.version_checks; - AdminDashboardNext.find().then(adminDashboardNextModel => { + AdminDashboardNext.find() + .then(adminDashboardNextModel => { + if (versionChecks) { + this.set( + "versionCheck", + VersionCheck.create(adminDashboardNextModel.version_check) + ); + } - if (versionChecks) { - this.set("versionCheck", VersionCheck.create(adminDashboardNextModel.version_check)); - } - - this.setProperties({ - dashboardFetchedAt: new Date(), - model: adminDashboardNextModel, - reports: adminDashboardNextModel.reports.map(x => Report.create(x)) + this.setProperties({ + dashboardFetchedAt: new Date(), + model: adminDashboardNextModel, + reports: adminDashboardNextModel.reports.map(x => Report.create(x)) + }); + }) + .catch(e => { + this.get("exceptionController").set("thrown", e.jqXHR); + this.replaceRoute("exception"); + }) + .finally(() => { + this.set("isLoading", false); }); - }).catch(e => { - this.get("exceptionController").set("thrown", e.jqXHR); - this.replaceRoute("exception"); - }).finally(() => { - this.set("isLoading", false); - }); } - if (!this.get("problemsFetchedAt") || moment().subtract(PROBLEMS_CHECK_MINUTES, "minutes").toDate() > this.get("problemsFetchedAt")) { + if ( + !this.get("problemsFetchedAt") || + moment() + .subtract(PROBLEMS_CHECK_MINUTES, "minutes") + .toDate() > this.get("problemsFetchedAt") + ) { this.loadProblems(); } }, @@ -58,21 +73,28 @@ export default Ember.Controller.extend({ loadProblems() { this.set("loadingProblems", true); this.set("problemsFetchedAt", new Date()); - AdminDashboardNext.fetchProblems().then(d => { - this.set("problems", d.problems); - }).finally(() => { - this.set("loadingProblems", false); - }); + AdminDashboardNext.fetchProblems() + .then(d => { + this.set("problems", d.problems); + }) + .finally(() => { + this.set("loadingProblems", false); + }); }, @computed("problemsFetchedAt") problemsTimestamp(problemsFetchedAt) { - return moment(problemsFetchedAt).locale("en").format("LLL"); + return moment(problemsFetchedAt) + .locale("en") + .format("LLL"); }, @computed("period") startDate(period) { - let fullDay = moment().locale("en").utc().subtract(1, "day"); + let fullDay = moment() + .locale("en") + .utc() + .subtract(1, "day"); switch (period) { case "yearly": @@ -94,12 +116,20 @@ export default Ember.Controller.extend({ @computed() lastWeek() { - return moment().locale("en").utc().endOf("day").subtract(1, "week"); + return moment() + .locale("en") + .utc() + .endOf("day") + .subtract(1, "week"); }, @computed() endDate() { - return moment().locale("en").utc().subtract(1, "day").endOf("day"); + return moment() + .locale("en") + .utc() + .subtract(1, "day") + .endOf("day"); }, @computed("model.attributes.updated_at") @@ -118,7 +148,7 @@ export default Ember.Controller.extend({ }, refreshProblems() { this.loadProblems(); - }, + } }, _reportsForPeriodURL(period) { diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 index 973cd3d57c9..9b545fc2fbe 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 @@ -1,50 +1,74 @@ -import AdminDashboard from 'admin/models/admin-dashboard'; -import Report from 'admin/models/report'; -import AdminUser from 'admin/models/admin-user'; -import computed from 'ember-addons/ember-computed-decorators'; +import AdminDashboard from "admin/models/admin-dashboard"; +import Report from "admin/models/report"; +import AdminUser from "admin/models/admin-user"; +import computed from "ember-addons/ember-computed-decorators"; +const ATTRIBUTES = [ + "disk_space", + "admins", + "moderators", + "silenced", + "suspended", + "top_traffic_sources", + "top_referred_topics", + "updated_at" +]; -const ATTRIBUTES = [ 'disk_space','admins', 'moderators', 'silenced', 'suspended', 'top_traffic_sources', - 'top_referred_topics', 'updated_at']; - -const REPORTS = [ 'global_reports', 'page_view_reports', 'private_message_reports', 'http_reports', - 'user_reports', 'mobile_reports']; +const REPORTS = [ + "global_reports", + "page_view_reports", + "private_message_reports", + "http_reports", + "user_reports", + "mobile_reports" +]; // This controller supports the default interface when you enter the admin section. export default Ember.Controller.extend({ loading: null, versionCheck: null, dashboardFetchedAt: null, - exceptionController: Ember.inject.controller('exception'), + exceptionController: Ember.inject.controller("exception"), fetchDashboard() { - if (!this.get('dashboardFetchedAt') || moment().subtract(30, 'minutes').toDate() > this.get('dashboardFetchedAt')) { - this.set('loading', true); - AdminDashboard.find().then(d => { - this.set('dashboardFetchedAt', new Date()); + if ( + !this.get("dashboardFetchedAt") || + moment() + .subtract(30, "minutes") + .toDate() > this.get("dashboardFetchedAt") + ) { + this.set("loading", true); + AdminDashboard.find() + .then(d => { + this.set("dashboardFetchedAt", new Date()); - REPORTS.forEach(name => this.set(name, d[name].map(r => Report.create(r)))); + REPORTS.forEach(name => + this.set(name, d[name].map(r => Report.create(r))) + ); - const topReferrers = d.top_referrers; - if (topReferrers && topReferrers.data) { - d.top_referrers.data = topReferrers.data.map(user => AdminUser.create(user)); - this.set('top_referrers', topReferrers); - } + const topReferrers = d.top_referrers; + if (topReferrers && topReferrers.data) { + d.top_referrers.data = topReferrers.data.map(user => + AdminUser.create(user) + ); + this.set("top_referrers", topReferrers); + } - ATTRIBUTES.forEach(a => this.set(a, d[a])); - }).catch(e => { - this.get('exceptionController').set('thrown', e.jqXHR); - this.replaceRoute('exception'); - }).finally(() => { - this.set('loading', false); - }); + ATTRIBUTES.forEach(a => this.set(a, d[a])); + }) + .catch(e => { + this.get("exceptionController").set("thrown", e.jqXHR); + this.replaceRoute("exception"); + }) + .finally(() => { + this.set("loading", false); + }); } }, - - @computed('updated_at') + @computed("updated_at") updatedTimestamp(updatedAt) { - return moment(updatedAt).format('LLL'); + return moment(updatedAt).format("LLL"); }, actions: { @@ -52,5 +76,4 @@ export default Ember.Controller.extend({ this.set("showTrafficReport", true); } } - }); diff --git a/app/assets/javascripts/admin/controllers/admin-email-bounced.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-bounced.js.es6 index ae75d187155..230fa07afb7 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-bounced.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-bounced.js.es6 @@ -1,6 +1,6 @@ -import AdminEmailLogsController from 'admin/controllers/admin-email-logs'; -import debounce from 'discourse/lib/debounce'; -import EmailLog from 'admin/models/email-log'; +import AdminEmailLogsController from "admin/controllers/admin-email-logs"; +import debounce from "discourse/lib/debounce"; +import EmailLog from "admin/models/email-log"; export default AdminEmailLogsController.extend({ filterEmailLogs: debounce(function() { diff --git a/app/assets/javascripts/admin/controllers/admin-email-incomings.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-incomings.js.es6 index a6acd9af78f..9dc59589fbd 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-incomings.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-incomings.js.es6 @@ -1,21 +1,25 @@ -import IncomingEmail from 'admin/models/incoming-email'; +import IncomingEmail from "admin/models/incoming-email"; export default Ember.Controller.extend({ loading: false, actions: { - loadMore() { - if (this.get("loading") || this.get("model.allLoaded")) { return; } - this.set('loading', true); + if (this.get("loading") || this.get("model.allLoaded")) { + return; + } + this.set("loading", true); IncomingEmail.findAll(this.get("filter"), this.get("model.length")) - .then(incoming => { - if (incoming.length < 50) { this.get("model").set("allLoaded", true); } - this.get("model").addObjects(incoming); - }).finally(() => { - this.set('loading', false); - }); + .then(incoming => { + if (incoming.length < 50) { + this.get("model").set("allLoaded", true); + } + this.get("model").addObjects(incoming); + }) + .finally(() => { + this.set("loading", false); + }); } } }); 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 fce0cb891ef..27b7bb498cf 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-index.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-index.js.es6 @@ -1,12 +1,11 @@ -import { ajax } from 'discourse/lib/ajax'; +import { ajax } from "discourse/lib/ajax"; export default Ember.Controller.extend({ - /** Is the "send test email" button disabled? @property sendTestEmailDisabled **/ - sendTestEmailDisabled: Em.computed.empty('testEmailAddress'), + sendTestEmailDisabled: Em.computed.empty("testEmailAddress"), /** Clears the 'sentTestEmail' property on successful send. @@ -14,8 +13,8 @@ export default Ember.Controller.extend({ @method testEmailAddressChanged **/ testEmailAddressChanged: function() { - this.set('sentTestEmail', false); - }.observes('testEmailAddress'), + this.set("sentTestEmail", false); + }.observes("testEmailAddress"), actions: { /** @@ -31,21 +30,28 @@ export default Ember.Controller.extend({ var self = this; ajax("/admin/email/test", { - type: 'POST', - data: { email_address: this.get('testEmailAddress') } - }).then(function () { - self.set('sentTestEmail', true); - }, function(e) { - if (e.responseJSON && e.responseJSON.errors) { - bootbox.alert(I18n.t('admin.email.error', { server_error: e.responseJSON.errors[0] })); - } else { - bootbox.alert(I18n.t('admin.email.test_error')); - } - }).finally(function() { - self.set('sendingEmail', false); - }); - + type: "POST", + data: { email_address: this.get("testEmailAddress") } + }) + .then( + function() { + self.set("sentTestEmail", true); + }, + function(e) { + if (e.responseJSON && e.responseJSON.errors) { + bootbox.alert( + I18n.t("admin.email.error", { + server_error: e.responseJSON.errors[0] + }) + ); + } else { + bootbox.alert(I18n.t("admin.email.test_error")); + } + } + ) + .finally(function() { + self.set("sendingEmail", false); + }); } } - }); diff --git a/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6 index 44a38dfa324..a86ae421115 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6 @@ -1,20 +1,25 @@ -import EmailLog from 'admin/models/email-log'; +import EmailLog from "admin/models/email-log"; export default Ember.Controller.extend({ loading: false, actions: { loadMore() { - if (this.get("loading") || this.get("model.allLoaded")) { return; } + if (this.get("loading") || this.get("model.allLoaded")) { + return; + } - this.set('loading', true); + this.set("loading", true); return EmailLog.findAll(this.get("filter"), this.get("model.length")) - .then(logs => { - if (logs.length < 50) { this.get("model").set("allLoaded", true); } - this.get("model").addObjects(logs); - }).finally(() => { - this.set('loading', false); - }); + .then(logs => { + if (logs.length < 50) { + this.get("model").set("allLoaded", true); + } + this.get("model").addObjects(logs); + }) + .finally(() => { + this.set("loading", false); + }); } } }); 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 eb03301c92d..9517a3f9a74 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,52 +1,60 @@ -import EmailPreview from 'admin/models/email-preview'; -import { popupAjaxError } from 'discourse/lib/ajax-error'; +import EmailPreview from "admin/models/email-preview"; +import { popupAjaxError } from "discourse/lib/ajax-error"; export default Ember.Controller.extend({ username: null, lastSeen: null, - emailEmpty: Ember.computed.empty('email'), - sendEmailDisabled: Ember.computed.or('emailEmpty', 'sendingEmail'), - showSendEmailForm: Ember.computed.notEmpty('model.html_content'), - htmlEmpty: Ember.computed.empty('model.html_content'), + emailEmpty: Ember.computed.empty("email"), + sendEmailDisabled: Ember.computed.or("emailEmpty", "sendingEmail"), + showSendEmailForm: Ember.computed.notEmpty("model.html_content"), + htmlEmpty: Ember.computed.empty("model.html_content"), actions: { refresh() { - const model = this.get('model'); + const model = this.get("model"); - this.set('loading', true); - this.set('sentEmail', false); + this.set("loading", true); + this.set("sentEmail", false); - let username = this.get('username'); + let username = this.get("username"); if (!username) { - username = this.currentUser.get('username'); - this.set('username', username); + username = this.currentUser.get("username"); + this.set("username", username); } - EmailPreview.findDigest(username, this.get('lastSeen')).then(email => { - model.setProperties(email.getProperties('html_content', 'text_content')); - this.set('loading', false); + EmailPreview.findDigest(username, this.get("lastSeen")).then(email => { + model.setProperties( + email.getProperties("html_content", "text_content") + ); + this.set("loading", false); }); }, toggleShowHtml() { - this.toggleProperty('showHtml'); + this.toggleProperty("showHtml"); }, sendEmail() { - this.set('sendingEmail', true); - this.set('sentEmail', false); + this.set("sendingEmail", true); + this.set("sentEmail", false); - EmailPreview.sendDigest(this.get('username'), this.get('lastSeen'), this.get('email')).then(result => { - if (result.errors) { - bootbox.alert(result.errors); - } else { - this.set('sentEmail', true); - } - }).catch(popupAjaxError).finally(() => { - this.set('sendingEmail', false); - }); + EmailPreview.sendDigest( + this.get("username"), + this.get("lastSeen"), + this.get("email") + ) + .then(result => { + if (result.errors) { + bootbox.alert(result.errors); + } else { + this.set("sentEmail", true); + } + }) + .catch(popupAjaxError) + .finally(() => { + this.set("sendingEmail", false); + }); } } - }); diff --git a/app/assets/javascripts/admin/controllers/admin-email-received.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-received.js.es6 index 69ebd5e4c49..a5f240fdbfd 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-received.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-received.js.es6 @@ -1,9 +1,11 @@ -import AdminEmailIncomingsController from 'admin/controllers/admin-email-incomings'; -import debounce from 'discourse/lib/debounce'; -import IncomingEmail from 'admin/models/incoming-email'; +import AdminEmailIncomingsController from "admin/controllers/admin-email-incomings"; +import debounce from "discourse/lib/debounce"; +import IncomingEmail from "admin/models/incoming-email"; export default AdminEmailIncomingsController.extend({ filterIncomingEmails: debounce(function() { - IncomingEmail.findAll(this.get("filter")).then(incomings => this.set("model", incomings)); + IncomingEmail.findAll(this.get("filter")).then(incomings => + this.set("model", incomings) + ); }, 250).observes("filter.{from,to,subject}") }); diff --git a/app/assets/javascripts/admin/controllers/admin-email-rejected.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-rejected.js.es6 index 317a669cd0e..b9341dd7e35 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-rejected.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-rejected.js.es6 @@ -1,9 +1,11 @@ -import AdminEmailIncomingsController from 'admin/controllers/admin-email-incomings'; -import debounce from 'discourse/lib/debounce'; -import IncomingEmail from 'admin/models/incoming-email'; +import AdminEmailIncomingsController from "admin/controllers/admin-email-incomings"; +import debounce from "discourse/lib/debounce"; +import IncomingEmail from "admin/models/incoming-email"; export default AdminEmailIncomingsController.extend({ filterIncomingEmails: debounce(function() { - IncomingEmail.findAll(this.get("filter")).then(incomings => this.set("model", incomings)); + IncomingEmail.findAll(this.get("filter")).then(incomings => + this.set("model", incomings) + ); }, 250).observes("filter.{from,to,subject,error}") }); 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 d73d640adca..691b017c6f0 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-sent.js.es6 @@ -1,6 +1,6 @@ -import AdminEmailLogsController from 'admin/controllers/admin-email-logs'; -import debounce from 'discourse/lib/debounce'; -import EmailLog from 'admin/models/email-log'; +import AdminEmailLogsController from "admin/controllers/admin-email-logs"; +import debounce from "discourse/lib/debounce"; +import EmailLog from "admin/models/email-log"; export default AdminEmailLogsController.extend({ filterEmailLogs: debounce(function() { 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 ae75d187155..230fa07afb7 100644 --- a/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-email-skipped.js.es6 @@ -1,6 +1,6 @@ -import AdminEmailLogsController from 'admin/controllers/admin-email-logs'; -import debounce from 'discourse/lib/debounce'; -import EmailLog from 'admin/models/email-log'; +import AdminEmailLogsController from "admin/controllers/admin-email-logs"; +import debounce from "discourse/lib/debounce"; +import EmailLog from "admin/models/email-log"; export default AdminEmailLogsController.extend({ filterEmailLogs: debounce(function() { diff --git a/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 b/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 index 266aa6975e6..33240955b55 100644 --- a/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 @@ -1,22 +1,20 @@ -import computed from 'ember-addons/ember-computed-decorators'; -import { popupAjaxError } from 'discourse/lib/ajax-error'; +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') + @computed("embedding.embeddable_hosts.@each.isCreated") showSecondary() { - const hosts = this.get('embedding.embeddable_hosts'); - return hosts.length && hosts.findBy('isCreated'); + const hosts = this.get("embedding.embeddable_hosts"); + return hosts.length && hosts.findBy("isCreated"); }, - @computed('embedding.base_url') + @computed("embedding.base_url") embeddingCode(baseUrl) { - - const html = -` + const html = ` gmail.com'); + fillIn(".search-query", "@gmail.com"); andThen(() => { - assert.ok(exists('.search-advanced-options span:contains("gmail.com")'), 'it escapes search term'); + assert.ok( + exists( + '.search-advanced-options span:contains("gmail.com")' + ), + "it escapes search term" + ); }); }); QUnit.test("update username through advanced search ui", assert => { visit("/search"); - fillIn('.search-query', 'none'); - fillIn('.search-advanced-options .user-selector', 'admin'); - click('.search-advanced-options .user-selector'); - keyEvent('.search-advanced-options .user-selector', 'keydown', 8); + fillIn(".search-query", "none"); + fillIn(".search-advanced-options .user-selector", "admin"); + click(".search-advanced-options .user-selector"); + keyEvent(".search-advanced-options .user-selector", "keydown", 8); andThen(() => { waitFor(assert, () => { - assert.ok(visible('.search-advanced-options .autocomplete'), '"autocomplete" popup is visible'); - assert.ok(exists('.search-advanced-options .autocomplete ul li a span.username:contains("admin")'), '"autocomplete" popup has an entry for "admin"'); + assert.ok( + visible(".search-advanced-options .autocomplete"), + '"autocomplete" popup is visible' + ); + assert.ok( + exists( + '.search-advanced-options .autocomplete ul li a span.username:contains("admin")' + ), + '"autocomplete" popup has an entry for "admin"' + ); - click('.search-advanced-options .autocomplete ul li a:first'); + click(".search-advanced-options .autocomplete ul li a:first"); andThen(() => { - assert.ok(exists('.search-advanced-options span:contains("admin")'), 'has "admin" pre-populated'); - assert.equal(find('.search-query').val(), "none @admin", 'has updated search term to "none user:admin"'); + assert.ok( + exists('.search-advanced-options span:contains("admin")'), + 'has "admin" pre-populated' + ); + assert.equal( + find(".search-query").val(), + "none @admin", + 'has updated search term to "none user:admin"' + ); }); }); }); }); QUnit.test("update category through advanced search ui", assert => { - const categoryChooser = selectKit('.search-advanced-options .category-chooser'); + const categoryChooser = selectKit( + ".search-advanced-options .category-chooser" + ); visit("/search"); - fillIn('.search-query', 'none'); - categoryChooser.expand().fillInFilter('faq').selectRowByValue(4); + fillIn(".search-query", "none"); + categoryChooser + .expand() + .fillInFilter("faq") + .selectRowByValue(4); andThen(() => { - assert.ok(exists('.search-advanced-options .badge-category:contains("faq")'), 'has "faq" populated'); - assert.equal(find('.search-query').val(), "none #faq", 'has updated search term to "none #faq"'); + assert.ok( + exists('.search-advanced-options .badge-category:contains("faq")'), + 'has "faq" populated' + ); + assert.equal( + find(".search-query").val(), + "none #faq", + 'has updated search term to "none #faq"' + ); }); }); @@ -176,109 +259,181 @@ QUnit.test("update category through advanced search ui", assert => { // }); // }); // -QUnit.test("update in:title filter through advanced search ui", async assert => { - await visit("/search"); - await fillIn('.search-query', 'none'); - await click('.search-advanced-options .in-title'); +QUnit.test( + "update in:title filter through advanced search ui", + async assert => { + await visit("/search"); + await fillIn(".search-query", "none"); + await click(".search-advanced-options .in-title"); - assert.ok(exists('.search-advanced-options .in-title:checked'), 'has "in title" populated'); - assert.equal(find('.search-query').val(), "none in:title", 'has updated search term to "none in:title"'); -}); + assert.ok( + exists(".search-advanced-options .in-title:checked"), + 'has "in title" populated' + ); + assert.equal( + find(".search-query").val(), + "none in:title", + 'has updated search term to "none in:title"' + ); + } +); -QUnit.test("update in:likes filter through advanced search ui", async assert => { - await visit("/search"); - await fillIn('.search-query', 'none'); - await click('.search-advanced-options .in-likes'); +QUnit.test( + "update in:likes filter through advanced search ui", + async assert => { + await visit("/search"); + await fillIn(".search-query", "none"); + await click(".search-advanced-options .in-likes"); - assert.ok(exists('.search-advanced-options .in-likes:checked'), 'has "I liked" populated'); - assert.equal(find('.search-query').val(), "none in:likes", 'has updated search term to "none in:likes"'); -}); + assert.ok( + exists(".search-advanced-options .in-likes:checked"), + 'has "I liked" populated' + ); + assert.equal( + find(".search-query").val(), + "none in:likes", + 'has updated search term to "none in:likes"' + ); + } +); QUnit.test("update in:private filter through advanced search ui", assert => { visit("/search"); - fillIn('.search-query', 'none'); - click('.search-advanced-options .in-private'); + fillIn(".search-query", "none"); + click(".search-advanced-options .in-private"); andThen(() => { - assert.ok(exists('.search-advanced-options .in-private:checked'), 'has "are in my messages" populated'); - assert.equal(find('.search-query').val(), "none in:private", 'has updated search term to "none in:private"'); + assert.ok( + exists(".search-advanced-options .in-private:checked"), + 'has "are in my messages" populated' + ); + assert.equal( + find(".search-query").val(), + "none in:private", + 'has updated search term to "none in:private"' + ); }); }); QUnit.test("update in:seen filter through advanced search ui", assert => { visit("/search"); - fillIn('.search-query', 'none'); - click('.search-advanced-options .in-seen'); + fillIn(".search-query", "none"); + click(".search-advanced-options .in-seen"); andThen(() => { - assert.ok(exists('.search-advanced-options .in-seen:checked'), 'it should check the right checkbox'); + assert.ok( + exists(".search-advanced-options .in-seen:checked"), + "it should check the right checkbox" + ); - assert.equal(find('.search-query').val(), "none in:seen", - 'it should update the search term' + assert.equal( + find(".search-query").val(), + "none in:seen", + "it should update the search term" ); }); }); QUnit.test("update in filter through advanced search ui", assert => { - const inSelector = selectKit('.search-advanced-options .select-kit#in'); + const inSelector = selectKit(".search-advanced-options .select-kit#in"); visit("/search"); - fillIn('.search-query', 'none'); - inSelector.expand().selectRowByValue('bookmarks'); + fillIn(".search-query", "none"); + inSelector.expand().selectRowByValue("bookmarks"); andThen(() => { - assert.ok(inSelector.rowByName("I bookmarked").exists(), 'has "I bookmarked" populated'); - assert.equal(find('.search-query').val(), "none in:bookmarks", 'has updated search term to "none in:bookmarks"'); + assert.ok( + inSelector.rowByName("I bookmarked").exists(), + 'has "I bookmarked" populated' + ); + assert.equal( + find(".search-query").val(), + "none in:bookmarks", + 'has updated search term to "none in:bookmarks"' + ); }); }); QUnit.test("update status through advanced search ui", assert => { - const statusSelector = selectKit('.search-advanced-options .select-kit#status'); + const statusSelector = selectKit( + ".search-advanced-options .select-kit#status" + ); visit("/search"); - fillIn('.search-query', 'none'); - statusSelector.expand().selectRowByValue('closed'); + fillIn(".search-query", "none"); + statusSelector.expand().selectRowByValue("closed"); andThen(() => { - assert.ok(statusSelector.rowByName("are closed").exists(), 'has "are closed" populated'); - assert.equal(find('.search-query').val(), "none status:closed", 'has updated search term to "none status:closed"'); + assert.ok( + statusSelector.rowByName("are closed").exists(), + 'has "are closed" populated' + ); + assert.equal( + find(".search-query").val(), + "none status:closed", + 'has updated search term to "none status:closed"' + ); }); }); QUnit.test("update post time through advanced search ui", assert => { - const postTimeSelector = selectKit('.search-advanced-options .select-kit#postTime'); + const postTimeSelector = selectKit( + ".search-advanced-options .select-kit#postTime" + ); visit("/search"); - fillIn('.search-query', 'none'); - fillIn('#search-post-date .date-picker', '2016-10-05'); - postTimeSelector.expand().selectRowByValue('after'); + fillIn(".search-query", "none"); + fillIn("#search-post-date .date-picker", "2016-10-05"); + postTimeSelector.expand().selectRowByValue("after"); andThen(() => { - assert.ok(postTimeSelector.rowByName("after").exists(), 'has "after" populated'); - assert.equal(find('.search-query').val(), "none after:2016-10-05", 'has updated search term to "none after:2016-10-05"'); + assert.ok( + postTimeSelector.rowByName("after").exists(), + 'has "after" populated' + ); + assert.equal( + find(".search-query").val(), + "none after:2016-10-05", + 'has updated search term to "none after:2016-10-05"' + ); }); }); QUnit.test("update min post count through advanced search ui", assert => { visit("/search"); - fillIn('.search-query', 'none'); - fillIn('#search-min-post-count', '5'); + fillIn(".search-query", "none"); + fillIn("#search-min-post-count", "5"); andThen(() => { - assert.equal(find('.search-advanced-options #search-min-post-count').val(), "5", 'has "5" populated'); - assert.equal(find('.search-query').val(), "none min_post_count:5", 'has updated search term to "none min_post_count:5"'); + assert.equal( + find(".search-advanced-options #search-min-post-count").val(), + "5", + 'has "5" populated' + ); + assert.equal( + find(".search-query").val(), + "none min_post_count:5", + 'has updated search term to "none min_post_count:5"' + ); }); }); QUnit.test("validate advanced search when initially empty", assert => { visit("/search?expanded=true"); - click('.search-advanced-options .in-likes'); + click(".search-advanced-options .in-likes"); andThen(() => { - assert.ok(exists('.search-advanced-options .in-likes:checked'), 'has "I liked" populated'); - assert.equal(find('.search-query').val(), "in:likes", 'has updated search term to "in:likes"'); + assert.ok( + exists(".search-advanced-options .in-likes:checked"), + 'has "I liked" populated' + ); + assert.equal( + find(".search-query").val(), + "in:likes", + 'has updated search term to "in:likes"' + ); }); }); diff --git a/test/javascripts/acceptance/search-test.js.es6 b/test/javascripts/acceptance/search-test.js.es6 index d388d67787d..b8d463977d5 100644 --- a/test/javascripts/acceptance/search-test.js.es6 +++ b/test/javascripts/acceptance/search-test.js.es6 @@ -1,124 +1,140 @@ import { acceptance, logIn } from "helpers/qunit-helpers"; acceptance("Search"); -QUnit.test("search", (assert) => { +QUnit.test("search", assert => { visit("/"); - click('#search-button'); + click("#search-button"); andThen(() => { - assert.ok(exists('#search-term'), 'it shows the search bar'); - assert.ok(!exists('.search-menu .results ul li'), 'no results by default'); + assert.ok(exists("#search-term"), "it shows the search bar"); + assert.ok(!exists(".search-menu .results ul li"), "no results by default"); }); - fillIn('#search-term', 'dev'); - keyEvent('#search-term', 'keyup', 16); + fillIn("#search-term", "dev"); + keyEvent("#search-term", "keyup", 16); andThen(() => { - assert.ok(exists('.search-menu .results ul li'), 'it shows results'); + assert.ok(exists(".search-menu .results ul li"), "it shows results"); }); - click('.show-help'); + click(".show-help"); andThen(() => { - assert.equal(find('.full-page-search').val(), 'dev', 'it shows the search term'); - assert.ok(exists('.search-advanced-options'), 'advanced search is expanded'); + assert.equal( + find(".full-page-search").val(), + "dev", + "it shows the search term" + ); + assert.ok( + exists(".search-advanced-options"), + "advanced search is expanded" + ); }); }); -QUnit.test("search for a tag", (assert) => { +QUnit.test("search for a tag", assert => { visit("/"); - click('#search-button'); + click("#search-button"); - fillIn('#search-term', 'evil'); - keyEvent('#search-term', 'keyup', 16); + fillIn("#search-term", "evil"); + keyEvent("#search-term", "keyup", 16); andThen(() => { - assert.ok(exists('.search-menu .results ul li'), 'it shows results'); + assert.ok(exists(".search-menu .results ul li"), "it shows results"); }); }); QUnit.test("search scope checkbox", assert => { visit("/c/bug"); - click('#search-button'); + click("#search-button"); andThen(() => { - assert.ok(exists('.search-context input:checked'), 'scope to category checkbox is checked'); + assert.ok( + exists(".search-context input:checked"), + "scope to category checkbox is checked" + ); }); - click('#search-button'); + click("#search-button"); visit("/t/internationalization-localization/280"); - click('#search-button'); + click("#search-button"); andThen(() => { - assert.not(exists('.search-context input:checked'), 'scope to topic checkbox is not checked'); + assert.not( + exists(".search-context input:checked"), + "scope to topic checkbox is not checked" + ); }); - click('#search-button'); + click("#search-button"); visit("/u/eviltrout"); - click('#search-button'); + click("#search-button"); andThen(() => { - assert.ok(exists('.search-context input:checked'), 'scope to user checkbox is checked'); + assert.ok( + exists(".search-context input:checked"), + "scope to user checkbox is checked" + ); }); }); QUnit.test("Search with context", assert => { visit("/t/internationalization-localization/280/1"); - click('#search-button'); - fillIn('#search-term', 'dev'); + click("#search-button"); + fillIn("#search-term", "dev"); click(".search-context input[type='checkbox']"); - keyEvent('#search-term', 'keyup', 16); + keyEvent("#search-term", "keyup", 16); andThen(() => { - assert.ok(exists('.search-menu .results ul li'), 'it shows results'); + assert.ok(exists(".search-menu .results ul li"), "it shows results"); assert.ok( - exists('.cooked span.highlight-strong'), - 'it should highlight the search term' + exists(".cooked span.highlight-strong"), + "it should highlight the search term" ); }); visit("/"); - click('#search-button'); + click("#search-button"); andThen(() => { assert.ok(!exists(".search-context input[type='checkbox']")); }); visit("/t/internationalization-localization/280/1"); - click('#search-button'); + click("#search-button"); andThen(() => { - assert.ok(!$('.search-context input[type=checkbox]').is(":checked")); + assert.ok(!$(".search-context input[type=checkbox]").is(":checked")); }); }); QUnit.test("Right filters are shown to anonymous users", assert => { - const inSelector = selectKit('.select-kit#in'); + const inSelector = selectKit(".select-kit#in"); visit("/search?expanded=true"); inSelector.expand(); andThen(() => { - assert.ok(inSelector.rowByValue('first').exists()); - assert.ok(inSelector.rowByValue('pinned').exists()); - assert.ok(inSelector.rowByValue('unpinned').exists()); - assert.ok(inSelector.rowByValue('wiki').exists()); - assert.ok(inSelector.rowByValue('images').exists()); + assert.ok(inSelector.rowByValue("first").exists()); + assert.ok(inSelector.rowByValue("pinned").exists()); + assert.ok(inSelector.rowByValue("unpinned").exists()); + assert.ok(inSelector.rowByValue("wiki").exists()); + assert.ok(inSelector.rowByValue("images").exists()); - assert.notOk(inSelector.rowByValue('unseen').exists()); - assert.notOk(inSelector.rowByValue('posted').exists()); - assert.notOk(inSelector.rowByValue('watching').exists()); - assert.notOk(inSelector.rowByValue('tracking').exists()); - assert.notOk(inSelector.rowByValue('bookmarks').exists()); + assert.notOk(inSelector.rowByValue("unseen").exists()); + assert.notOk(inSelector.rowByValue("posted").exists()); + assert.notOk(inSelector.rowByValue("watching").exists()); + assert.notOk(inSelector.rowByValue("tracking").exists()); + assert.notOk(inSelector.rowByValue("bookmarks").exists()); - assert.notOk(exists('.search-advanced-options .in-likes')); - assert.notOk(exists('.search-advanced-options .in-private')); - assert.notOk(exists('.search-advanced-options .in-seen')); + assert.notOk(exists(".search-advanced-options .in-likes")); + assert.notOk(exists(".search-advanced-options .in-private")); + assert.notOk(exists(".search-advanced-options .in-seen")); }); }); QUnit.test("Right filters are shown to logged-in users", assert => { - const inSelector = selectKit('.select-kit#in'); + const inSelector = selectKit(".select-kit#in"); logIn(); Discourse.reset(); @@ -127,20 +143,20 @@ QUnit.test("Right filters are shown to logged-in users", assert => { inSelector.expand(); andThen(() => { - assert.ok(inSelector.rowByValue('first').exists()); - assert.ok(inSelector.rowByValue('pinned').exists()); - assert.ok(inSelector.rowByValue('unpinned').exists()); - assert.ok(inSelector.rowByValue('wiki').exists()); - assert.ok(inSelector.rowByValue('images').exists()); + assert.ok(inSelector.rowByValue("first").exists()); + assert.ok(inSelector.rowByValue("pinned").exists()); + assert.ok(inSelector.rowByValue("unpinned").exists()); + assert.ok(inSelector.rowByValue("wiki").exists()); + assert.ok(inSelector.rowByValue("images").exists()); - assert.ok(inSelector.rowByValue('unseen').exists()); - assert.ok(inSelector.rowByValue('posted').exists()); - assert.ok(inSelector.rowByValue('watching').exists()); - assert.ok(inSelector.rowByValue('tracking').exists()); - assert.ok(inSelector.rowByValue('bookmarks').exists()); + assert.ok(inSelector.rowByValue("unseen").exists()); + assert.ok(inSelector.rowByValue("posted").exists()); + assert.ok(inSelector.rowByValue("watching").exists()); + assert.ok(inSelector.rowByValue("tracking").exists()); + assert.ok(inSelector.rowByValue("bookmarks").exists()); - assert.ok(exists('.search-advanced-options .in-likes')); - assert.ok(exists('.search-advanced-options .in-private')); - assert.ok(exists('.search-advanced-options .in-seen')); + assert.ok(exists(".search-advanced-options .in-likes")); + assert.ok(exists(".search-advanced-options .in-private")); + assert.ok(exists(".search-advanced-options .in-seen")); }); }); diff --git a/test/javascripts/acceptance/shared-drafts-test.js.es6 b/test/javascripts/acceptance/shared-drafts-test.js.es6 index 6aea6ec38be..28f2ce0ca37 100644 --- a/test/javascripts/acceptance/shared-drafts-test.js.es6 +++ b/test/javascripts/acceptance/shared-drafts-test.js.es6 @@ -2,18 +2,18 @@ import { acceptance } from "helpers/qunit-helpers"; acceptance("Shared Drafts", { loggedIn: true }); -QUnit.test('Viewing', assert => { +QUnit.test("Viewing", assert => { visit("/t/some-topic/9"); andThen(() => { - assert.ok(find('.shared-draft-controls').length === 1); - let categoryChooser = selectKit('.shared-draft-controls .category-chooser'); - assert.equal(categoryChooser.header().value(), '3'); + assert.ok(find(".shared-draft-controls").length === 1); + let categoryChooser = selectKit(".shared-draft-controls .category-chooser"); + assert.equal(categoryChooser.header().value(), "3"); }); - click('.publish-shared-draft'); - click('.bootbox .btn-primary'); + click(".publish-shared-draft"); + click(".bootbox .btn-primary"); andThen(() => { - assert.ok(find('.shared-draft-controls').length === 0); + assert.ok(find(".shared-draft-controls").length === 0); }); }); diff --git a/test/javascripts/acceptance/sign-in-test.js.es6 b/test/javascripts/acceptance/sign-in-test.js.es6 index 1320be56ee2..0a075db20f0 100644 --- a/test/javascripts/acceptance/sign-in-test.js.es6 +++ b/test/javascripts/acceptance/sign-in-test.js.es6 @@ -5,23 +5,29 @@ QUnit.test("sign in", assert => { visit("/"); click("header .login-button"); andThen(() => { - assert.ok(exists('.login-modal'), "it shows the login modal"); + assert.ok(exists(".login-modal"), "it shows the login modal"); }); // Test invalid password first - fillIn('#login-account-name', 'eviltrout'); - fillIn('#login-account-password', 'incorrect'); - click('.modal-footer .btn-primary'); + fillIn("#login-account-name", "eviltrout"); + fillIn("#login-account-password", "incorrect"); + click(".modal-footer .btn-primary"); andThen(() => { - assert.ok(exists('#modal-alert:visible'), 'it displays the login error'); - assert.not(exists('.modal-footer .btn-primary:disabled'), "enables the login button"); + assert.ok(exists("#modal-alert:visible"), "it displays the login error"); + assert.not( + exists(".modal-footer .btn-primary:disabled"), + "enables the login button" + ); }); // Use the correct password - fillIn('#login-account-password', 'correct'); - click('.modal-footer .btn-primary'); + fillIn("#login-account-password", "correct"); + click(".modal-footer .btn-primary"); andThen(() => { - assert.ok(exists('.modal-footer .btn-primary:disabled'), "disables the login button"); + assert.ok( + exists(".modal-footer .btn-primary:disabled"), + "disables the login button" + ); }); }); @@ -30,21 +36,27 @@ QUnit.test("sign in - not activated", assert => { andThen(() => { click("header .login-button"); andThen(() => { - assert.ok(exists('.login-modal'), "it shows the login modal"); + assert.ok(exists(".login-modal"), "it shows the login modal"); }); - fillIn('#login-account-name', 'eviltrout'); - fillIn('#login-account-password', 'not-activated'); - click('.modal-footer .btn-primary'); + fillIn("#login-account-name", "eviltrout"); + fillIn("#login-account-password", "not-activated"); + click(".modal-footer .btn-primary"); andThen(() => { - assert.equal(find('.modal-body b').text(), 'eviltrout@example.com'); - assert.ok(!exists('.modal-body small'), 'it escapes the email address'); + assert.equal( + find(".modal-body b").text(), + "eviltrout@example.com" + ); + assert.ok(!exists(".modal-body small"), "it escapes the email address"); }); - click('.modal-footer button.resend'); + click(".modal-footer button.resend"); andThen(() => { - assert.equal(find('.modal-body b').text(), 'current@example.com'); - assert.ok(!exists('.modal-body small'), 'it escapes the email address'); + assert.equal( + find(".modal-body b").text(), + "current@example.com" + ); + assert.ok(!exists(".modal-body small"), "it escapes the email address"); }); }); }); @@ -54,24 +66,28 @@ QUnit.test("sign in - not activated - edit email", assert => { andThen(() => { click("header .login-button"); andThen(() => { - assert.ok(exists('.login-modal'), "it shows the login modal"); + assert.ok(exists(".login-modal"), "it shows the login modal"); }); - fillIn('#login-account-name', 'eviltrout'); - fillIn('#login-account-password', 'not-activated-edit'); - click('.modal-footer .btn-primary'); - click('.modal-footer button.edit-email'); + fillIn("#login-account-name", "eviltrout"); + fillIn("#login-account-password", "not-activated-edit"); + click(".modal-footer .btn-primary"); + click(".modal-footer button.edit-email"); andThen(() => { - assert.equal(find('.activate-new-email').val(), 'current@example.com'); - assert.equal(find('.modal-footer .btn-primary:disabled').length, 1, "must change email"); + assert.equal(find(".activate-new-email").val(), "current@example.com"); + assert.equal( + find(".modal-footer .btn-primary:disabled").length, + 1, + "must change email" + ); }); - fillIn('.activate-new-email', 'different@example.com'); + fillIn(".activate-new-email", "different@example.com"); andThen(() => { - assert.equal(find('.modal-footer .btn-primary:disabled').length, 0); + assert.equal(find(".modal-footer .btn-primary:disabled").length, 0); }); click(".modal-footer .btn-primary"); andThen(() => { - assert.equal(find('.modal-body b').text(), 'different@example.com'); + assert.equal(find(".modal-body b").text(), "different@example.com"); }); }); }); @@ -81,25 +97,37 @@ QUnit.test("second factor", assert => { click("header .login-button"); andThen(() => { - assert.ok(exists('.login-modal'), "it shows the login modal"); + assert.ok(exists(".login-modal"), "it shows the login modal"); }); - fillIn('#login-account-name', 'eviltrout'); - fillIn('#login-account-password', 'need-second-factor'); - click('.modal-footer .btn-primary'); + fillIn("#login-account-name", "eviltrout"); + fillIn("#login-account-password", "need-second-factor"); + click(".modal-footer .btn-primary"); andThen(() => { - assert.not(exists('#modal-alert:visible'), 'it hides the login error'); - assert.not(exists('#credentials:visible'), 'it hides the username and password prompt'); - assert.ok(exists('#second-factor:visible'), 'it displays the second factor prompt'); - assert.not(exists('.modal-footer .btn-primary:disabled'), "enables the login button"); + assert.not(exists("#modal-alert:visible"), "it hides the login error"); + assert.not( + exists("#credentials:visible"), + "it hides the username and password prompt" + ); + assert.ok( + exists("#second-factor:visible"), + "it displays the second factor prompt" + ); + assert.not( + exists(".modal-footer .btn-primary:disabled"), + "enables the login button" + ); }); - fillIn('#login-second-factor', '123456'); - click('.modal-footer .btn-primary'); + fillIn("#login-second-factor", "123456"); + click(".modal-footer .btn-primary"); andThen(() => { - assert.ok(exists('.modal-footer .btn-primary:disabled'), "disables the login button"); + assert.ok( + exists(".modal-footer .btn-primary:disabled"), + "disables the login button" + ); }); }); @@ -108,29 +136,47 @@ QUnit.test("create account", assert => { click("header .sign-up-button"); andThen(() => { - assert.ok(exists('.create-account'), "it shows the create account modal"); - assert.ok(exists('.modal-footer .btn-primary:disabled'), 'create account is disabled at first'); + assert.ok(exists(".create-account"), "it shows the create account modal"); + assert.ok( + exists(".modal-footer .btn-primary:disabled"), + "create account is disabled at first" + ); }); - fillIn('#new-account-name', 'Dr. Good Tuna'); - fillIn('#new-account-password', 'cool password bro'); + fillIn("#new-account-name", "Dr. Good Tuna"); + fillIn("#new-account-password", "cool password bro"); // Check username - fillIn('#new-account-email', 'good.tuna@test.com'); - fillIn('#new-account-username', 'taken'); + fillIn("#new-account-email", "good.tuna@test.com"); + fillIn("#new-account-username", "taken"); andThen(() => { - assert.ok(exists('#username-validation.bad'), 'the username validation is bad'); - assert.ok(exists('.modal-footer .btn-primary:disabled'), 'create account is still disabled'); + assert.ok( + exists("#username-validation.bad"), + "the username validation is bad" + ); + assert.ok( + exists(".modal-footer .btn-primary:disabled"), + "create account is still disabled" + ); }); - fillIn('#new-account-username', 'goodtuna'); + fillIn("#new-account-username", "goodtuna"); andThen(() => { - assert.ok(exists('#username-validation.good'), 'the username validation is good'); - assert.not(exists('.modal-footer .btn-primary:disabled'), 'create account is enabled'); + assert.ok( + exists("#username-validation.good"), + "the username validation is good" + ); + assert.not( + exists(".modal-footer .btn-primary:disabled"), + "create account is enabled" + ); }); - click('.modal-footer .btn-primary'); + click(".modal-footer .btn-primary"); andThen(() => { - assert.ok(exists('.modal-footer .btn-primary:disabled'), "create account is disabled"); + assert.ok( + exists(".modal-footer .btn-primary:disabled"), + "create account is disabled" + ); }); }); diff --git a/test/javascripts/acceptance/static-test.js.es6 b/test/javascripts/acceptance/static-test.js.es6 index 97592dbd4a9..47fa81dd5ec 100644 --- a/test/javascripts/acceptance/static-test.js.es6 +++ b/test/javascripts/acceptance/static-test.js.es6 @@ -4,30 +4,34 @@ acceptance("Static"); QUnit.test("Static Pages", assert => { visit("/faq"); andThen(() => { - assert.ok($('body.static-faq').length, "has the body class"); + assert.ok($("body.static-faq").length, "has the body class"); assert.ok(exists(".body-page"), "The content is present"); }); visit("/guidelines"); andThen(() => { - assert.ok($('body.static-guidelines').length, "has the body class"); + assert.ok($("body.static-guidelines").length, "has the body class"); assert.ok(exists(".body-page"), "The content is present"); }); visit("/tos"); andThen(() => { - assert.ok($('body.static-tos').length, "has the body class"); + assert.ok($("body.static-tos").length, "has the body class"); assert.ok(exists(".body-page"), "The content is present"); }); visit("/privacy"); andThen(() => { - assert.ok($('body.static-privacy').length, "has the body class"); + assert.ok($("body.static-privacy").length, "has the body class"); assert.ok(exists(".body-page"), "The content is present"); }); visit("/login"); andThen(() => { - assert.equal(currentPath(), "discovery.latest", "it redirects them to latest unless `login_required`"); + assert.equal( + currentPath(), + "discovery.latest", + "it redirects them to latest unless `login_required`" + ); }); -}); \ No newline at end of file +}); diff --git a/test/javascripts/acceptance/tag-hashtag-test.js.es6 b/test/javascripts/acceptance/tag-hashtag-test.js.es6 index 559b9ff9269..e71e7251754 100644 --- a/test/javascripts/acceptance/tag-hashtag-test.js.es6 +++ b/test/javascripts/acceptance/tag-hashtag-test.js.es6 @@ -4,40 +4,49 @@ acceptance("Tag Hashtag", { loggedIn: true, settings: { tagging_enabled: true }, beforeEach() { - const response = (object) => { - return [ - 200, - {"Content-Type": "application/json"}, - object - ]; + const response = object => { + return [200, { "Content-Type": "application/json" }, object]; }; - server.get('/tags/filter/search', () => { //eslint-disable-line - return response({ results: [{ text: 'monkey', count: 1 }] }); + server.get("/tags/filter/search", () => { + //eslint-disable-line + return response({ results: [{ text: "monkey", count: 1 }] }); }); - server.get('/category_hashtags/check', () => { //eslint-disable-line + server.get("/category_hashtags/check", () => { + //eslint-disable-line return response({ valid: [] }); }); - server.get('/tags/check', () => { //eslint-disable-line - return response({ valid: [{ value: 'monkey', url: '/tags/monkey' }] }); + server.get("/tags/check", () => { + //eslint-disable-line + return response({ valid: [{ value: "monkey", url: "/tags/monkey" }] }); }); } }); QUnit.test("tag is cooked properly", assert => { visit("/t/internationalization-localization/280"); - click('#topic-footer-buttons .btn.create'); + click("#topic-footer-buttons .btn.create"); - fillIn('.d-editor-input', "this is a tag hashtag #monkey::tag"); + fillIn(".d-editor-input", "this is a tag hashtag #monkey::tag"); andThen(() => { // TODO: Test that the autocomplete shows - assert.equal(find('.d-editor-preview:visible').html().trim(), "this is a tag hashtag #monkey
"); + assert.equal( + find(".d-editor-preview:visible") + .html() + .trim(), + 'this is a tag hashtag #monkey
' + ); }); - click('#reply-control .btn.create'); + click("#reply-control .btn.create"); andThen(() => { - assert.equal(find('.topic-post:last .cooked').html().trim(), "this is a tag hashtag #monkey
"); + assert.equal( + find(".topic-post:last .cooked") + .html() + .trim(), + 'this is a tag hashtag #monkey
' + ); }); -}); \ No newline at end of file +}); diff --git a/test/javascripts/acceptance/tags-test.js.es6 b/test/javascripts/acceptance/tags-test.js.es6 index 8971f83ee33..ebaf1218eec 100644 --- a/test/javascripts/acceptance/tags-test.js.es6 +++ b/test/javascripts/acceptance/tags-test.js.es6 @@ -5,8 +5,8 @@ QUnit.test("list the tags", assert => { visit("/tags"); andThen(() => { - assert.ok($('body.tags-page').length, "has the body class"); - assert.ok(exists('.tag-eviltrout'), "shows the evil trout tag"); + assert.ok($("body.tags-page").length, "has the body class"); + assert.ok(exists(".tag-eviltrout"), "shows the evil trout tag"); }); }); @@ -17,48 +17,70 @@ acceptance("Tags listed by group", { } }); - QUnit.test("list the tags in groups", assert => { - server.get('/tags', () => { // eslint-disable-line no-undef + server.get("/tags", () => { + // eslint-disable-line no-undef return [ 200, { "Content-Type": "application/json" }, { - "tags":[{id: 'planned', text: 'planned', count: 7, pm_count: 0}], - "extras": { "tag_groups": [ - {id: 2, name: "Ford Cars", tags: [ - {id: 'escort', text: 'escort', count: 1, pm_count: 0}, - {id: 'focus', text: 'focus', count: 3, pm_count: 0} - ]}, - {id: 1, name: "Honda Cars", tags: [ - {id: 'civic', text: 'civic', count: 4, pm_count: 0}, - {id: 'accord', text: 'accord', count: 2, pm_count: 0} - ]}, - {id: 1, name: "Makes", tags: [ - {id: 'ford', text: 'ford', count: 5, pm_count: 0}, - {id: 'honda', text: 'honda', count: 6, pm_count: 0} - ]} - ]} + tags: [{ id: "planned", text: "planned", count: 7, pm_count: 0 }], + extras: { + tag_groups: [ + { + id: 2, + name: "Ford Cars", + tags: [ + { id: "escort", text: "escort", count: 1, pm_count: 0 }, + { id: "focus", text: "focus", count: 3, pm_count: 0 } + ] + }, + { + id: 1, + name: "Honda Cars", + tags: [ + { id: "civic", text: "civic", count: 4, pm_count: 0 }, + { id: "accord", text: "accord", count: 2, pm_count: 0 } + ] + }, + { + id: 1, + name: "Makes", + tags: [ + { id: "ford", text: "ford", count: 5, pm_count: 0 }, + { id: "honda", text: "honda", count: 6, pm_count: 0 } + ] + } + ] + } } ]; }); - visit('/tags'); + visit("/tags"); andThen(() => { - assert.equal($('.tag-list').length, 4, "shows separate lists for the 3 groups and the ungrouped tags"); - assert.ok( - _.isEqual( - _.map($('.tag-list h3'), i => { return $(i).text(); } ), - ['Ford Cars', 'Honda Cars', 'Makes', 'Other Tags'] - ), - 'shown in given order and with tags that are not in a group' + assert.equal( + $(".tag-list").length, + 4, + "shows separate lists for the 3 groups and the ungrouped tags" ); assert.ok( _.isEqual( - _.map($('.tag-list:first .discourse-tag'), i => { return $(i).text(); }), - ['focus', 'escort'] + _.map($(".tag-list h3"), i => { + return $(i).text(); + }), + ["Ford Cars", "Honda Cars", "Makes", "Other Tags"] ), - 'shows the tags in default sort (by count)' + "shown in given order and with tags that are not in a group" + ); + assert.ok( + _.isEqual( + _.map($(".tag-list:first .discourse-tag"), i => { + return $(i).text(); + }), + ["focus", "escort"] + ), + "shows the tags in default sort (by count)" ); }); }); diff --git a/test/javascripts/acceptance/topic-anonymous-test.js.es6 b/test/javascripts/acceptance/topic-anonymous-test.js.es6 index c0eff198659..1ec1ed32f57 100644 --- a/test/javascripts/acceptance/topic-anonymous-test.js.es6 +++ b/test/javascripts/acceptance/topic-anonymous-test.js.es6 @@ -6,7 +6,10 @@ QUnit.test("Enter a Topic", assert => { andThen(() => { assert.ok(exists("#topic"), "The topic was rendered"); assert.ok(exists("#topic .cooked"), "The topic has cooked posts"); - assert.ok(find('.shared-draft-notice').length === 0, "no shared draft unless there's a dest category id"); + assert.ok( + find(".shared-draft-notice").length === 0, + "no shared draft unless there's a dest category id" + ); }); }); @@ -21,7 +24,10 @@ QUnit.test("Enter a 404 topic", assert => { visit("/t/not-found/404"); andThen(() => { assert.ok(!exists("#topic"), "The topic was not rendered"); - assert.ok(find(".not-found").text() === "not found", "it renders the error message"); + assert.ok( + find(".not-found").text() === "not found", + "it renders the error message" + ); }); }); diff --git a/test/javascripts/acceptance/topic-discovery-test.js.es6 b/test/javascripts/acceptance/topic-discovery-test.js.es6 index 458c3471a03..e66382be969 100644 --- a/test/javascripts/acceptance/topic-discovery-test.js.es6 +++ b/test/javascripts/acceptance/topic-discovery-test.js.es6 @@ -4,43 +4,64 @@ acceptance("Topic Discovery"); QUnit.test("Visit Discovery Pages", assert => { visit("/"); andThen(() => { - assert.ok($('body.navigation-topics').length, "has the default navigation"); + assert.ok($("body.navigation-topics").length, "has the default navigation"); assert.ok(exists(".topic-list"), "The list of topics was rendered"); - assert.ok(exists('.topic-list .topic-list-item'), "has topics"); + assert.ok(exists(".topic-list .topic-list-item"), "has topics"); }); visit("/c/bug"); andThen(() => { assert.ok(exists(".topic-list"), "The list of topics was rendered"); - assert.ok(exists('.topic-list .topic-list-item'), "has topics"); - assert.ok(!exists('.category-list'), "doesn't render subcategories"); - assert.ok($('body.category-bug').length, "has a custom css class for the category id on the body"); + assert.ok(exists(".topic-list .topic-list-item"), "has topics"); + assert.ok(!exists(".category-list"), "doesn't render subcategories"); + assert.ok( + $("body.category-bug").length, + "has a custom css class for the category id on the body" + ); }); visit("/categories"); andThen(() => { - assert.ok($('body.navigation-categories').length, "has the body class"); - assert.ok($('body.category-bug').length === 0, "removes the custom category class"); - assert.ok(exists('.category'), "has a list of categories"); - assert.ok($('body.categories-list').length, "has a custom class to indicate categories"); + assert.ok($("body.navigation-categories").length, "has the body class"); + assert.ok( + $("body.category-bug").length === 0, + "removes the custom category class" + ); + assert.ok(exists(".category"), "has a list of categories"); + assert.ok( + $("body.categories-list").length, + "has a custom class to indicate categories" + ); }); visit("/top"); andThen(() => { - assert.ok($('body.categories-list').length === 0, "removes the `categories-list` class"); - assert.ok(exists('.topic-list .topic-list-item'), "has topics"); + assert.ok( + $("body.categories-list").length === 0, + "removes the `categories-list` class" + ); + assert.ok(exists(".topic-list .topic-list-item"), "has topics"); }); visit("/c/feature"); andThen(() => { assert.ok(exists(".topic-list"), "The list of topics was rendered"); - assert.ok(exists(".category-boxes"), "The list of subcategories were rendered with box style"); + assert.ok( + exists(".category-boxes"), + "The list of subcategories were rendered with box style" + ); }); visit("/c/dev"); andThen(() => { assert.ok(exists(".topic-list"), "The list of topics was rendered"); - assert.ok(exists(".category-boxes-with-topics"), "The list of subcategories were rendered with box-with-featured-topics style"); - assert.ok(exists(".category-boxes-with-topics .featured-topics"), "The featured topics are there too"); + assert.ok( + exists(".category-boxes-with-topics"), + "The list of subcategories were rendered with box-with-featured-topics style" + ); + assert.ok( + exists(".category-boxes-with-topics .featured-topics"), + "The featured topics are there too" + ); }); -}); \ No newline at end of file +}); diff --git a/test/javascripts/acceptance/topic-edit-timer-test.js.es6 b/test/javascripts/acceptance/topic-edit-timer-test.js.es6 index b3ed4df7440..f437f298840 100644 --- a/test/javascripts/acceptance/topic-edit-timer-test.js.es6 +++ b/test/javascripts/acceptance/topic-edit-timer-test.js.es6 @@ -1,163 +1,207 @@ -import { acceptance, replaceCurrentUser } from 'helpers/qunit-helpers'; -acceptance('Topic - Edit timer', { loggedIn: true }); +import { acceptance, replaceCurrentUser } from "helpers/qunit-helpers"; +acceptance("Topic - Edit timer", { loggedIn: true }); -QUnit.test('default', assert => { - const timerType = selectKit('.select-kit.timer-type'); - const futureDateInputSelector = selectKit('.future-date-input-selector'); +QUnit.test("default", assert => { + const timerType = selectKit(".select-kit.timer-type"); + const futureDateInputSelector = selectKit(".future-date-input-selector"); - visit('/t/internationalization-localization'); - click('.toggle-admin-menu'); - click('.topic-admin-status-update button'); + visit("/t/internationalization-localization"); + click(".toggle-admin-menu"); + click(".topic-admin-status-update button"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Select a timeframe'); + assert.equal( + futureDateInputSelector.header().title(), + "Select a timeframe" + ); assert.equal(futureDateInputSelector.header().value(), null); }); - click('#private-topic-timer'); + click("#private-topic-timer"); andThen(() => { - assert.equal(timerType.header().title(), 'Remind Me'); - assert.equal(timerType.header().value(), 'reminder'); + assert.equal(timerType.header().title(), "Remind Me"); + assert.equal(timerType.header().value(), "reminder"); - assert.equal(futureDateInputSelector.header().title(), 'Select a timeframe'); + assert.equal( + futureDateInputSelector.header().title(), + "Select a timeframe" + ); assert.equal(futureDateInputSelector.header().value(), null); }); }); -QUnit.test('autoclose - specific time', assert => { - const futureDateInputSelector = selectKit('.future-date-input-selector'); +QUnit.test("autoclose - specific time", assert => { + const futureDateInputSelector = selectKit(".future-date-input-selector"); - visit('/t/internationalization-localization'); - click('.toggle-admin-menu'); - click('.topic-admin-status-update button'); + visit("/t/internationalization-localization"); + click(".toggle-admin-menu"); + click(".topic-admin-status-update button"); - futureDateInputSelector.expand().selectRowByValue('next_week'); + futureDateInputSelector.expand().selectRowByValue("next_week"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Next week'); - assert.equal(futureDateInputSelector.header().value(), 'next_week'); + assert.equal(futureDateInputSelector.header().title(), "Next week"); + assert.equal(futureDateInputSelector.header().value(), "next_week"); const regex = /will automatically close in/g; - const html = find('.future-date-input .topic-status-info').html().trim(); + const html = find(".future-date-input .topic-status-info") + .html() + .trim(); assert.ok(regex.test(html)); }); }); -QUnit.test('autoclose', assert => { - const futureDateInputSelector = selectKit('.future-date-input-selector'); +QUnit.test("autoclose", assert => { + const futureDateInputSelector = selectKit(".future-date-input-selector"); - visit('/t/internationalization-localization'); - click('.toggle-admin-menu'); - click('.topic-admin-status-update button'); + visit("/t/internationalization-localization"); + click(".toggle-admin-menu"); + click(".topic-admin-status-update button"); - futureDateInputSelector.expand().selectRowByValue('next_week'); + futureDateInputSelector.expand().selectRowByValue("next_week"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Next week'); - assert.equal(futureDateInputSelector.header().value(), 'next_week'); + assert.equal(futureDateInputSelector.header().title(), "Next week"); + assert.equal(futureDateInputSelector.header().value(), "next_week"); const regex = /will automatically close in/g; - const html = find('.future-date-input .topic-status-info').html().trim(); + const html = find(".future-date-input .topic-status-info") + .html() + .trim(); assert.ok(regex.test(html)); }); - futureDateInputSelector.expand().selectRowByValue('pick_date_and_time'); + futureDateInputSelector.expand().selectRowByValue("pick_date_and_time"); - fillIn('.future-date-input .date-picker', '2099-11-24'); + fillIn(".future-date-input .date-picker", "2099-11-24"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Pick date and time'); - assert.equal(futureDateInputSelector.header().value(), 'pick_date_and_time'); + assert.equal( + futureDateInputSelector.header().title(), + "Pick date and time" + ); + assert.equal( + futureDateInputSelector.header().value(), + "pick_date_and_time" + ); const regex = /will automatically close in/g; - const html = find('.future-date-input .topic-status-info').html().trim(); + const html = find(".future-date-input .topic-status-info") + .html() + .trim(); assert.ok(regex.test(html)); }); - futureDateInputSelector.expand().selectRowByValue('set_based_on_last_post'); + futureDateInputSelector.expand().selectRowByValue("set_based_on_last_post"); - fillIn('.future-date-input input[type=number]', '2'); + fillIn(".future-date-input input[type=number]", "2"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Close based on last post'); - assert.equal(futureDateInputSelector.header().value(), 'set_based_on_last_post'); + assert.equal( + futureDateInputSelector.header().title(), + "Close based on last post" + ); + assert.equal( + futureDateInputSelector.header().value(), + "set_based_on_last_post" + ); const regex = /This topic will close.*after the last reply/g; - const html = find('.future-date-input .topic-status-info').html().trim(); + const html = find(".future-date-input .topic-status-info") + .html() + .trim(); assert.ok(regex.test(html)); }); }); -QUnit.test('close temporarily', assert => { - const timerType = selectKit('.select-kit.timer-type'); - const futureDateInputSelector = selectKit('.future-date-input-selector'); +QUnit.test("close temporarily", assert => { + const timerType = selectKit(".select-kit.timer-type"); + const futureDateInputSelector = selectKit(".future-date-input-selector"); - visit('/t/internationalization-localization'); - click('.toggle-admin-menu'); - click('.topic-admin-status-update button'); + visit("/t/internationalization-localization"); + click(".toggle-admin-menu"); + click(".topic-admin-status-update button"); - timerType.expand().selectRowByValue('open'); + timerType.expand().selectRowByValue("open"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Select a timeframe'); + assert.equal( + futureDateInputSelector.header().title(), + "Select a timeframe" + ); assert.equal(futureDateInputSelector.header().value(), null); }); - futureDateInputSelector.expand().selectRowByValue('next_week'); + futureDateInputSelector.expand().selectRowByValue("next_week"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Next week'); - assert.equal(futureDateInputSelector.header().value(), 'next_week'); + assert.equal(futureDateInputSelector.header().title(), "Next week"); + assert.equal(futureDateInputSelector.header().value(), "next_week"); const regex = /will automatically open in/g; - const html = find('.future-date-input .topic-status-info').html().trim(); + const html = find(".future-date-input .topic-status-info") + .html() + .trim(); assert.ok(regex.test(html)); }); - futureDateInputSelector.expand().selectRowByValue('pick_date_and_time'); + futureDateInputSelector.expand().selectRowByValue("pick_date_and_time"); - fillIn('.future-date-input .date-picker', '2099-11-24'); + fillIn(".future-date-input .date-picker", "2099-11-24"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Pick date and time'); - assert.equal(futureDateInputSelector.header().value(), 'pick_date_and_time'); + assert.equal( + futureDateInputSelector.header().title(), + "Pick date and time" + ); + assert.equal( + futureDateInputSelector.header().value(), + "pick_date_and_time" + ); const regex = /will automatically open in/g; - const html = find('.future-date-input .topic-status-info').html().trim(); + const html = find(".future-date-input .topic-status-info") + .html() + .trim(); assert.ok(regex.test(html)); }); }); -QUnit.test('schedule', assert => { - const timerType = selectKit('.select-kit.timer-type'); - const categoryChooser = selectKit('.modal-body .category-chooser'); - const futureDateInputSelector = selectKit('.future-date-input-selector'); +QUnit.test("schedule", assert => { + const timerType = selectKit(".select-kit.timer-type"); + const categoryChooser = selectKit(".modal-body .category-chooser"); + const futureDateInputSelector = selectKit(".future-date-input-selector"); - visit('/t/internationalization-localization'); - click('.toggle-admin-menu'); - click('.topic-admin-status-update button'); + visit("/t/internationalization-localization"); + click(".toggle-admin-menu"); + click(".topic-admin-status-update button"); - timerType.expand().selectRowByValue('publish_to_category'); + timerType.expand().selectRowByValue("publish_to_category"); andThen(() => { - assert.equal(categoryChooser.header().title(), 'uncategorized'); + assert.equal(categoryChooser.header().title(), "uncategorized"); assert.equal(categoryChooser.header().value(), null); - assert.equal(futureDateInputSelector.header().title(), 'Select a timeframe'); + assert.equal( + futureDateInputSelector.header().title(), + "Select a timeframe" + ); assert.equal(futureDateInputSelector.header().value(), null); }); - categoryChooser.expand().selectRowByValue('7'); + categoryChooser.expand().selectRowByValue("7"); - futureDateInputSelector.expand().selectRowByValue('next_week'); + futureDateInputSelector.expand().selectRowByValue("next_week"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Next week'); - assert.equal(futureDateInputSelector.header().value(), 'next_week'); + assert.equal(futureDateInputSelector.header().title(), "Next week"); + assert.equal(futureDateInputSelector.header().value(), "next_week"); const regex = /will be published to #dev/g; - const text = find('.future-date-input .topic-status-info').text().trim(); + const text = find(".future-date-input .topic-status-info") + .text() + .trim(); assert.ok(regex.test(text)); }); }); @@ -165,11 +209,11 @@ QUnit.test('schedule', assert => { QUnit.test("TL4 can't auto-delete", assert => { replaceCurrentUser({ staff: false, trust_level: 4 }); - visit('/t/internationalization-localization'); - click('.toggle-admin-menu'); - click('.topic-admin-status-update button'); + visit("/t/internationalization-localization"); + click(".toggle-admin-menu"); + click(".topic-admin-status-update button"); - const timerType = selectKit('.select-kit.timer-type'); + const timerType = selectKit(".select-kit.timer-type"); timerType.expand(); @@ -178,29 +222,34 @@ QUnit.test("TL4 can't auto-delete", assert => { }); }); -QUnit.test('auto delete', assert => { - const timerType = selectKit('.select-kit.timer-type'); - const futureDateInputSelector = selectKit('.future-date-input-selector'); +QUnit.test("auto delete", assert => { + const timerType = selectKit(".select-kit.timer-type"); + const futureDateInputSelector = selectKit(".future-date-input-selector"); - visit('/t/internationalization-localization'); - click('.toggle-admin-menu'); - click('.topic-admin-status-update button'); + visit("/t/internationalization-localization"); + click(".toggle-admin-menu"); + click(".topic-admin-status-update button"); - timerType.expand().selectRowByValue('delete'); + timerType.expand().selectRowByValue("delete"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Select a timeframe'); + assert.equal( + futureDateInputSelector.header().title(), + "Select a timeframe" + ); assert.equal(futureDateInputSelector.header().value(), null); }); - futureDateInputSelector.expand().selectRowByValue('two_weeks'); + futureDateInputSelector.expand().selectRowByValue("two_weeks"); andThen(() => { - assert.equal(futureDateInputSelector.header().title(), 'Two Weeks'); - assert.equal(futureDateInputSelector.header().value(), 'two_weeks'); + assert.equal(futureDateInputSelector.header().title(), "Two Weeks"); + assert.equal(futureDateInputSelector.header().value(), "two_weeks"); const regex = /will be automatically deleted/g; - const html = find('.future-date-input .topic-status-info').html().trim(); + const html = find(".future-date-input .topic-status-info") + .html() + .trim(); assert.ok(regex.test(html)); }); }); diff --git a/test/javascripts/acceptance/topic-notifications-button-test.js.es6 b/test/javascripts/acceptance/topic-notifications-button-test.js.es6 index 4fe88775954..5e9e032ac36 100644 --- a/test/javascripts/acceptance/topic-notifications-button-test.js.es6 +++ b/test/javascripts/acceptance/topic-notifications-button-test.js.es6 @@ -3,21 +3,20 @@ acceptance("Topic Notifications button", { loggedIn: true, beforeEach() { const response = object => { - return [ - 200, - { "Content-Type": "application/json" }, - object - ]; + return [200, { "Content-Type": "application/json" }, object]; }; - server.post('/t/280/notifications', () => { // eslint-disable-line no-undef + server.post("/t/280/notifications", () => { + // eslint-disable-line no-undef return response({}); }); } }); QUnit.test("Updating topic notification level", assert => { - const notificationOptions = selectKit("#topic-footer-buttons .topic-notifications-options"); + const notificationOptions = selectKit( + "#topic-footer-buttons .topic-notifications-options" + ); visit("/t/internationalization-localization/280"); diff --git a/test/javascripts/acceptance/topic-test.js.es6 b/test/javascripts/acceptance/topic-test.js.es6 index b84afe844f7..926530f67e6 100644 --- a/test/javascripts/acceptance/topic-test.js.es6 +++ b/test/javascripts/acceptance/topic-test.js.es6 @@ -4,17 +4,17 @@ acceptance("Topic", { loggedIn: true }); QUnit.test("Share Popup", assert => { visit("/t/internationalization-localization/280"); andThen(() => { - assert.ok(!exists('#share-link.visible'), 'it is not visible'); + assert.ok(!exists("#share-link.visible"), "it is not visible"); }); click("button[data-share-url]"); andThen(() => { - assert.ok(exists('#share-link.visible'), 'it shows the popup'); + assert.ok(exists("#share-link.visible"), "it shows the popup"); }); - click('#share-link .close-share'); + click("#share-link .close-share"); andThen(() => { - assert.ok(!exists('#share-link.visible'), 'it closes the popup'); + assert.ok(!exists("#share-link.visible"), "it closes the popup"); }); // TODO tgxworld This fails on Travis but we need to push the security fix out @@ -33,57 +33,67 @@ QUnit.test("Share Popup", assert => { QUnit.test("Showing and hiding the edit controls", assert => { visit("/t/internationalization-localization/280"); - click('#topic-title .d-icon-pencil'); + click("#topic-title .d-icon-pencil"); andThen(() => { - assert.ok(exists('#edit-title'), 'it shows the editing controls'); - assert.ok(!exists('.title-wrapper .remove-featured-link'), 'link to remove featured link is not shown'); + assert.ok(exists("#edit-title"), "it shows the editing controls"); + assert.ok( + !exists(".title-wrapper .remove-featured-link"), + "link to remove featured link is not shown" + ); }); - fillIn('#edit-title', 'this is the new title'); - click('#topic-title .cancel-edit'); + fillIn("#edit-title", "this is the new title"); + click("#topic-title .cancel-edit"); andThen(() => { - assert.ok(!exists('#edit-title'), 'it hides the editing controls'); + assert.ok(!exists("#edit-title"), "it hides the editing controls"); }); }); QUnit.test("Updating the topic title and category", assert => { - const categoryChooser = selectKit('.title-wrapper .category-chooser'); + const categoryChooser = selectKit(".title-wrapper .category-chooser"); visit("/t/internationalization-localization/280"); - click('#topic-title .d-icon-pencil'); - fillIn('#edit-title', 'this is the new title'); + click("#topic-title .d-icon-pencil"); + fillIn("#edit-title", "this is the new title"); categoryChooser.expand().selectRowByValue(4); - click('#topic-title .submit-edit'); + click("#topic-title .submit-edit"); andThen(() => { - assert.equal(find('#topic-title .badge-category').text(), 'faq', 'it displays the new category'); - assert.equal(find('.fancy-title').text().trim(), 'this is the new title', 'it displays the new title'); + assert.equal( + find("#topic-title .badge-category").text(), + "faq", + "it displays the new category" + ); + assert.equal( + find(".fancy-title") + .text() + .trim(), + "this is the new title", + "it displays the new title" + ); }); }); QUnit.test("Marking a topic as wiki", assert => { - server.put('/posts/398/wiki', () => { // eslint-disable-line no-undef - return [ - 200, - { "Content-Type": "application/json" }, - {} - ]; + server.put("/posts/398/wiki", () => { + // eslint-disable-line no-undef + return [200, { "Content-Type": "application/json" }, {}]; }); visit("/t/internationalization-localization/280"); andThen(() => { - assert.ok(find('a.wiki').length === 0, 'it does not show the wiki icon'); + assert.ok(find("a.wiki").length === 0, "it does not show the wiki icon"); }); - click('.topic-post:eq(0) button.show-more-actions'); - click('.topic-post:eq(0) button.show-post-admin-menu'); - click('.btn.wiki'); + click(".topic-post:eq(0) button.show-more-actions"); + click(".topic-post:eq(0) button.show-post-admin-menu"); + click(".btn.wiki"); andThen(() => { - assert.ok(find('a.wiki').length === 1, 'it shows the wiki icon'); + assert.ok(find("a.wiki").length === 1, "it shows the wiki icon"); }); }); @@ -93,15 +103,22 @@ QUnit.test("Reply as new topic", assert => { click(".reply-as-new-topic a"); andThen(() => { - assert.ok(exists('.d-editor-input'), 'the composer input is visible'); + assert.ok(exists(".d-editor-input"), "the composer input is visible"); assert.equal( - find('.d-editor-input').val().trim(), - `Continuing the discussion from [Internationalization / localization](${window.location.origin}/t/internationalization-localization/280):`, + find(".d-editor-input") + .val() + .trim(), + `Continuing the discussion from [Internationalization / localization](${ + window.location.origin + }/t/internationalization-localization/280):`, "it fills composer with the ring string" ); assert.equal( - selectKit('.category-chooser').header().value(), "2", + selectKit(".category-chooser") + .header() + .value(), + "2", "it fills category selector with the right category" ); }); @@ -113,28 +130,35 @@ QUnit.test("Reply as new message", assert => { click(".reply-as-new-topic a"); andThen(() => { - assert.ok(exists('.d-editor-input'), 'the composer input is visible'); + assert.ok(exists(".d-editor-input"), "the composer input is visible"); assert.equal( - find('.d-editor-input').val().trim(), - `Continuing the discussion from [PM for testing](${window.location.origin}/t/pm-for-testing/12):`, + find(".d-editor-input") + .val() + .trim(), + `Continuing the discussion from [PM for testing](${ + window.location.origin + }/t/pm-for-testing/12):`, "it fills composer with the ring string" ); - const targets = find('.item span', '.composer-fields'); + const targets = find(".item span", ".composer-fields"); assert.equal( - $(targets[0]).text(), "someguy", + $(targets[0]).text(), + "someguy", "it fills up the composer with the right user to start the PM to" ); assert.equal( - $(targets[1]).text(), "test", + $(targets[1]).text(), + "test", "it fills up the composer with the right user to start the PM to" ); assert.equal( - $(targets[2]).text(), "Group", + $(targets[2]).text(), + "Group", "it fills up the composer with the right group to start the PM to" ); }); @@ -145,8 +169,11 @@ QUnit.test("Visit topic routes", assert => { andThen(() => { assert.equal( - find('.fancy-title').text().trim(), 'PM for testing', - 'it routes to the right topic' + find(".fancy-title") + .text() + .trim(), + "PM for testing", + "it routes to the right topic" ); }); @@ -154,22 +181,31 @@ QUnit.test("Visit topic routes", assert => { andThen(() => { assert.equal( - find('.fancy-title').text().trim(), 'Internationalization / localization', - 'it routes to the right topic' + find(".fancy-title") + .text() + .trim(), + "Internationalization / localization", + "it routes to the right topic" ); }); }); QUnit.test("Updating the topic title with emojis", assert => { visit("/t/internationalization-localization/280"); - click('#topic-title .d-icon-pencil'); + click("#topic-title .d-icon-pencil"); - fillIn('#edit-title', 'emojis title :bike: :blonde_woman:t6:'); + fillIn("#edit-title", "emojis title :bike: :blonde_woman:t6:"); - click('#topic-title .submit-edit'); + click("#topic-title .submit-edit"); andThen(() => { - assert.equal(find('.fancy-title').html().trim(), 'emojis titlehello world
'); + assert.equal(this.get("value"), "hello **world**"); + assert.equal( + this.$(".d-editor-preview") + .html() + .trim(), + "hello world
" + ); }); } }); -componentTest('preview sanitizes HTML', { - template: '{{d-editor value=value}}', +componentTest("preview sanitizes HTML", { + template: "{{d-editor value=value}}", test(assert) { - fillIn('.d-editor-input', `">`); + fillIn(".d-editor-input", `">`); andThen(() => { - assert.equal(this.$('.d-editor-preview').html().trim(), '\">
'); + assert.equal( + this.$(".d-editor-preview") + .html() + .trim(), + '">
' + ); }); } }); -componentTest('updating the value refreshes the preview', { - template: '{{d-editor value=value}}', +componentTest("updating the value refreshes the preview", { + template: "{{d-editor value=value}}", beforeEach() { - this.set('value', 'evil trout'); + this.set("value", "evil trout"); }, test(assert) { - assert.equal(this.$('.d-editor-preview').html().trim(), 'evil trout
'); + assert.equal( + this.$(".d-editor-preview") + .html() + .trim(), + "evil trout
" + ); - andThen(() => this.set('value', 'zogstrip')); - andThen(() => assert.equal(this.$('.d-editor-preview').html().trim(), 'zogstrip
')); + andThen(() => this.set("value", "zogstrip")); + andThen(() => + assert.equal( + this.$(".d-editor-preview") + .html() + .trim(), + "zogstrip
" + ) + ); } }); @@ -51,12 +73,12 @@ function jumpEnd(textarea) { function testCase(title, testFunc) { componentTest(title, { - template: '{{d-editor value=value}}', + template: "{{d-editor value=value}}", beforeEach() { - this.set('value', 'hello world.'); + this.set("value", "hello world."); }, test(assert) { - const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + const textarea = jumpEnd(this.$("textarea.d-editor-input")[0]); testFunc.call(this, assert, textarea); } }); @@ -64,12 +86,12 @@ function testCase(title, testFunc) { function composerTestCase(title, testFunc) { componentTest(title, { - template: '{{d-editor value=value composerEvents=true}}', + template: "{{d-editor value=value composerEvents=true}}", beforeEach() { - this.set('value', 'hello world.'); + this.set("value", "hello world."); }, test(assert) { - const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + const textarea = jumpEnd(this.$("textarea.d-editor-input")[0]); testFunc.call(this, assert, textarea); } }); @@ -81,7 +103,7 @@ testCase(`selecting the space before a word`, function(assert, textarea) { click(`button.bold`); andThen(() => { - assert.equal(this.get('value'), `hello **w**orld.`); + assert.equal(this.get("value"), `hello **w**orld.`); assert.equal(textarea.selectionStart, 8); assert.equal(textarea.selectionEnd, 9); }); @@ -93,7 +115,7 @@ testCase(`selecting the space after a word`, function(assert, textarea) { click(`button.bold`); andThen(() => { - assert.equal(this.get('value'), `**hello** world.`); + assert.equal(this.get("value"), `**hello** world.`); assert.equal(textarea.selectionStart, 2); assert.equal(textarea.selectionEnd, 7); }); @@ -103,7 +125,7 @@ testCase(`bold button with no selection`, function(assert, textarea) { click(`button.bold`); andThen(() => { const example = I18n.t(`composer.bold_text`); - assert.equal(this.get('value'), `hello world.**${example}**`); + assert.equal(this.get("value"), `hello world.**${example}**`); assert.equal(textarea.selectionStart, 14); assert.equal(textarea.selectionEnd, 14 + example.length); }); @@ -115,21 +137,21 @@ testCase(`bold button with a selection`, function(assert, textarea) { click(`button.bold`); andThen(() => { - assert.equal(this.get('value'), `hello **world**.`); + assert.equal(this.get("value"), `hello **world**.`); assert.equal(textarea.selectionStart, 8); assert.equal(textarea.selectionEnd, 13); }); click(`button.bold`); andThen(() => { - assert.equal(this.get('value'), 'hello world.'); + assert.equal(this.get("value"), "hello world."); assert.equal(textarea.selectionStart, 6); assert.equal(textarea.selectionEnd, 11); }); }); -testCase(`bold with a multiline selection`, function (assert, textarea) { - this.set('value', "hello\n\nworld\n\ntest."); +testCase(`bold with a multiline selection`, function(assert, textarea) { + this.set("value", "hello\n\nworld\n\ntest."); andThen(() => { textarea.selectionStart = 0; @@ -138,14 +160,14 @@ testCase(`bold with a multiline selection`, function (assert, textarea) { click(`button.bold`); andThen(() => { - assert.equal(this.get('value'), `**hello**\n\n**world**\n\ntest.`); + assert.equal(this.get("value"), `**hello**\n\n**world**\n\ntest.`); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 20); }); click(`button.bold`); andThen(() => { - assert.equal(this.get('value'), `hello\n\nworld\n\ntest.`); + assert.equal(this.get("value"), `hello\n\nworld\n\ntest.`); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 12); }); @@ -155,7 +177,7 @@ testCase(`italic button with no selection`, function(assert, textarea) { click(`button.italic`); andThen(() => { const example = I18n.t(`composer.italic_text`); - assert.equal(this.get('value'), `hello world._${example}_`); + assert.equal(this.get("value"), `hello world._${example}_`); assert.equal(textarea.selectionStart, 13); assert.equal(textarea.selectionEnd, 13 + example.length); @@ -168,21 +190,21 @@ testCase(`italic button with a selection`, function(assert, textarea) { click(`button.italic`); andThen(() => { - assert.equal(this.get('value'), `hello _world_.`); + assert.equal(this.get("value"), `hello _world_.`); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 12); }); click(`button.italic`); andThen(() => { - assert.equal(this.get('value'), 'hello world.'); + assert.equal(this.get("value"), "hello world."); assert.equal(textarea.selectionStart, 6); assert.equal(textarea.selectionEnd, 11); }); }); -testCase(`italic with a multiline selection`, function (assert, textarea) { - this.set('value', "hello\n\nworld\n\ntest."); +testCase(`italic with a multiline selection`, function(assert, textarea) { + this.set("value", "hello\n\nworld\n\ntest."); andThen(() => { textarea.selectionStart = 0; @@ -191,108 +213,117 @@ testCase(`italic with a multiline selection`, function (assert, textarea) { click(`button.italic`); andThen(() => { - assert.equal(this.get('value'), `_hello_\n\n_world_\n\ntest.`); + assert.equal(this.get("value"), `_hello_\n\n_world_\n\ntest.`); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 16); }); click(`button.italic`); andThen(() => { - assert.equal(this.get('value'), `hello\n\nworld\n\ntest.`); + assert.equal(this.get("value"), `hello\n\nworld\n\ntest.`); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 12); }); }); -testCase('link modal (cancel)', function(assert) { - assert.equal(this.$('.insert-link.hidden').length, 1); +testCase("link modal (cancel)", function(assert) { + assert.equal(this.$(".insert-link.hidden").length, 1); - click('button.link'); + click("button.link"); andThen(() => { - assert.equal(this.$('.insert-link.hidden').length, 0); + assert.equal(this.$(".insert-link.hidden").length, 0); }); - click('.insert-link button.btn-danger'); + click(".insert-link button.btn-danger"); andThen(() => { - assert.equal(this.$('.insert-link.hidden').length, 1); - assert.equal(this.get('value'), 'hello world.'); + assert.equal(this.$(".insert-link.hidden").length, 1); + assert.equal(this.get("value"), "hello world."); }); }); -testCase('link modal (simple link)', function(assert, textarea) { - click('button.link'); +testCase("link modal (simple link)", function(assert, textarea) { + click("button.link"); - const url = 'http://eviltrout.com'; + const url = "http://eviltrout.com"; - fillIn('.insert-link input.link-url', url); - click('.insert-link button.btn-primary'); + fillIn(".insert-link input.link-url", url); + click(".insert-link button.btn-primary"); andThen(() => { - assert.equal(this.$('.insert-link.hidden').length, 1); - assert.equal(this.get('value'), `hello world.[${url}](${url})`); + assert.equal(this.$(".insert-link.hidden").length, 1); + assert.equal(this.get("value"), `hello world.[${url}](${url})`); assert.equal(textarea.selectionStart, 13); assert.equal(textarea.selectionEnd, 13 + url.length); }); }); -testCase('link modal auto http addition', function(assert) { - click('button.link'); - fillIn('.insert-link input.link-url', 'sam.com'); - click('.insert-link button.btn-primary'); +testCase("link modal auto http addition", function(assert) { + click("button.link"); + fillIn(".insert-link input.link-url", "sam.com"); + click(".insert-link button.btn-primary"); andThen(() => { - assert.equal(this.get('value'), `hello world.[sam.com](http://sam.com)`); + assert.equal(this.get("value"), `hello world.[sam.com](http://sam.com)`); }); }); -testCase('link modal (simple link) with selected text', function(assert, textarea) { +testCase("link modal (simple link) with selected text", function( + assert, + textarea +) { textarea.selectionStart = 0; textarea.selectionEnd = 12; - click('button.link'); + click("button.link"); andThen(() => { - assert.equal(this.$('input.link-text')[0].value, 'hello world.'); + assert.equal(this.$("input.link-text")[0].value, "hello world."); }); - fillIn('.insert-link input.link-url', 'http://eviltrout.com'); - click('.insert-link button.btn-primary'); + fillIn(".insert-link input.link-url", "http://eviltrout.com"); + click(".insert-link button.btn-primary"); andThen(() => { - assert.equal(this.$('.insert-link.hidden').length, 1); - assert.equal(this.get('value'), '[hello world.](http://eviltrout.com)'); + assert.equal(this.$(".insert-link.hidden").length, 1); + assert.equal(this.get("value"), "[hello world.](http://eviltrout.com)"); }); }); -testCase('link modal (link with description)', function(assert) { - click('button.link'); - fillIn('.insert-link input.link-url', 'http://eviltrout.com'); - fillIn('.insert-link input.link-text', 'evil trout'); - click('.insert-link button.btn-primary'); +testCase("link modal (link with description)", function(assert) { + click("button.link"); + fillIn(".insert-link input.link-url", "http://eviltrout.com"); + fillIn(".insert-link input.link-text", "evil trout"); + click(".insert-link button.btn-primary"); andThen(() => { - assert.equal(this.$('.insert-link.hidden').length, 1); - assert.equal(this.get('value'), 'hello world.[evil trout](http://eviltrout.com)'); + assert.equal(this.$(".insert-link.hidden").length, 1); + assert.equal( + this.get("value"), + "hello world.[evil trout](http://eviltrout.com)" + ); }); }); -componentTest('advanced code', { - template: '{{d-editor value=value}}', +componentTest("advanced code", { + template: "{{d-editor value=value}}", beforeEach() { - this.siteSettings.code_formatting_style = '4-spaces-indent'; - this.set('value', -` + this.siteSettings.code_formatting_style = "4-spaces-indent"; + this.set( + "value", + ` function xyz(x, y, z) { if (y === z) { return true; } } -` ); +` + ); }, test(assert) { - const textarea = this.$('textarea.d-editor-input')[0]; + const textarea = this.$("textarea.d-editor-input")[0]; textarea.selectionStart = 0; textarea.selectionEnd = textarea.value.length; - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -` + assert.equal( + this.get("value"), + ` function xyz(x, y, z) { if (y === z) { return true; @@ -302,54 +333,52 @@ function xyz(x, y, z) { ); }); } - }); -componentTest('code button', { - template: '{{d-editor value=value}}', +componentTest("code button", { + template: "{{d-editor value=value}}", beforeEach() { - this.siteSettings.code_formatting_style = '4-spaces-indent'; + this.siteSettings.code_formatting_style = "4-spaces-indent"; }, test(assert) { - const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + const textarea = jumpEnd(this.$("textarea.d-editor-input")[0]); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -` ${I18n.t('composer.code_text')}` - ); + assert.equal(this.get("value"), ` ${I18n.t("composer.code_text")}`); - this.set('value', "first line\n\nsecond line\n\nthird line"); + this.set("value", "first line\n\nsecond line\n\nthird line"); textarea.selectionStart = 11; textarea.selectionEnd = 11; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`first line - ${I18n.t('composer.code_text')} + assert.equal( + this.get("value"), + `first line + ${I18n.t("composer.code_text")} second line third line` ); - this.set('value', "first line\n\nsecond line\n\nthird line"); + this.set("value", "first line\n\nsecond line\n\nthird line"); }); - - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`first line + assert.equal( + this.get("value"), + `first line second line -third line\`${I18n.t('composer.code_title')}\`` +third line\`${I18n.t("composer.code_title")}\`` ); - this.set('value', "first line\n\nsecond line\n\nthird line"); + this.set("value", "first line\n\nsecond line\n\nthird line"); }); andThen(() => { @@ -357,16 +386,17 @@ third line\`${I18n.t('composer.code_title')}\`` textarea.selectionEnd = 5; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`first\`${I18n.t('composer.code_title')}\` line + assert.equal( + this.get("value"), + `first\`${I18n.t("composer.code_title")}\` line second line third line` ); - this.set('value', "first line\n\nsecond line\n\nthird line"); + this.set("value", "first line\n\nsecond line\n\nthird line"); }); andThen(() => { @@ -374,16 +404,22 @@ third line` textarea.selectionEnd = 10; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), "first `line`\n\nsecond line\n\nthird line"); + assert.equal( + this.get("value"), + "first `line`\n\nsecond line\n\nthird line" + ); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 11); }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), "first line\n\nsecond line\n\nthird line"); + assert.equal( + this.get("value"), + "first line\n\nsecond line\n\nthird line" + ); assert.equal(textarea.selectionStart, 6); assert.equal(textarea.selectionEnd, 10); @@ -391,35 +427,42 @@ third line` textarea.selectionEnd = 23; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), " first line\n\n second line\n\nthird line"); + assert.equal( + this.get("value"), + " first line\n\n second line\n\nthird line" + ); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 31); }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), "first line\n\nsecond line\n\nthird line"); + assert.equal( + this.get("value"), + "first line\n\nsecond line\n\nthird line" + ); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 23); }); } }); -componentTest('code fences', { - template: '{{d-editor value=value}}', +componentTest("code fences", { + template: "{{d-editor value=value}}", beforeEach() { - this.set('value', ''); + this.set("value", ""); }, test(assert) { - const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + const textarea = jumpEnd(this.$("textarea.d-editor-input")[0]); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`\`\`\` + assert.equal( + this.get("value"), + `\`\`\` ${I18n.t("composer.paste_code_text")} \`\`\`` ); @@ -427,16 +470,17 @@ ${I18n.t("composer.paste_code_text")} assert.equal(textarea.selectionStart, 4); assert.equal(textarea.selectionEnd, 27); - this.set('value', 'first line\nsecond line\nthird line'); + this.set("value", "first line\nsecond line\nthird line"); textarea.selectionStart = 0; textarea.selectionEnd = textarea.value.length; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`\`\`\` + assert.equal( + this.get("value"), + `\`\`\` first line second line third line @@ -447,33 +491,38 @@ third line assert.equal(textarea.selectionStart, textarea.value.length); assert.equal(textarea.selectionEnd, textarea.value.length); - this.set('value', 'first line\nsecond line\nthird line'); + this.set("value", "first line\nsecond line\nthird line"); textarea.selectionStart = 0; textarea.selectionEnd = 0; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`\`${I18n.t('composer.code_title')}\`first line + assert.equal( + this.get("value"), + `\`${I18n.t("composer.code_title")}\`first line second line third line` ); assert.equal(textarea.selectionStart, 1); - assert.equal(textarea.selectionEnd, I18n.t('composer.code_title').length + 1); + assert.equal( + textarea.selectionEnd, + I18n.t("composer.code_title").length + 1 + ); - this.set('value', 'first line\nsecond line\nthird line'); + this.set("value", "first line\nsecond line\nthird line"); textarea.selectionStart = 0; textarea.selectionEnd = 10; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`\`first line\` + assert.equal( + this.get("value"), + `\`first line\` second line third line` ); @@ -481,16 +530,17 @@ third line` assert.equal(textarea.selectionStart, 1); assert.equal(textarea.selectionEnd, 11); - this.set('value', 'first line\nsecond line\nthird line'); + this.set("value", "first line\nsecond line\nthird line"); textarea.selectionStart = 0; textarea.selectionEnd = 23; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), -`\`\`\` + assert.equal( + this.get("value"), + `\`\`\` first line second line \`\`\` @@ -500,15 +550,18 @@ third line` assert.equal(textarea.selectionStart, 30); assert.equal(textarea.selectionEnd, 30); - this.set('value', 'first line\nsecond line\nthird line'); + this.set("value", "first line\nsecond line\nthird line"); textarea.selectionStart = 6; textarea.selectionEnd = 17; }); - click('button.code'); + click("button.code"); andThen(() => { - assert.equal(this.get('value'), `first \n\`\`\`\nline\nsecond\n\`\`\`\n line\nthird line`); + assert.equal( + this.get("value"), + `first \n\`\`\`\nline\nsecond\n\`\`\`\n line\nthird line` + ); assert.equal(textarea.selectionStart, 27); assert.equal(textarea.selectionEnd, 27); @@ -516,71 +569,69 @@ third line` } }); - componentTest("quote button - empty lines", { - template: '{{d-editor value=value composerEvents=true}}', + template: "{{d-editor value=value composerEvents=true}}", beforeEach() { - this.set('value', "one\n\ntwo\n\nthree"); + this.set("value", "one\n\ntwo\n\nthree"); }, test(assert) { - const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + const textarea = jumpEnd(this.$("textarea.d-editor-input")[0]); andThen(() => { textarea.selectionStart = 0; }); - click('button.quote'); + click("button.quote"); andThen(() => { - assert.equal(this.get('value'), "> one\n> \n> two\n> \n> three"); + assert.equal(this.get("value"), "> one\n> \n> two\n> \n> three"); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 25); }); - click('button.quote'); + click("button.quote"); andThen(() => { - assert.equal(this.get('value'), "one\n\ntwo\n\nthree"); + assert.equal(this.get("value"), "one\n\ntwo\n\nthree"); }); } }); componentTest("quote button - selecting empty lines", { - template: '{{d-editor value=value composerEvents=true}}', + template: "{{d-editor value=value composerEvents=true}}", beforeEach() { - this.set('value', "one\n\n\n\ntwo"); + this.set("value", "one\n\n\n\ntwo"); }, test(assert) { - const textarea = jumpEnd(this.$('textarea.d-editor-input')[0]); + const textarea = jumpEnd(this.$("textarea.d-editor-input")[0]); andThen(() => { textarea.selectionStart = 6; textarea.selectionEnd = 10; }); - click('button.quote'); + click("button.quote"); andThen(() => { - assert.equal(this.get('value'), "one\n\n\n> \n> two"); + assert.equal(this.get("value"), "one\n\n\n> \n> two"); }); } }); -testCase('quote button', function(assert, textarea) { - +testCase("quote button", function(assert, textarea) { andThen(() => { textarea.selectionStart = 6; textarea.selectionEnd = 9; }); - click('button.quote'); + click("button.quote"); andThen(() => { - assert.equal(this.get('value'), 'hello\n\n> wor\n\nld.'); + assert.equal(this.get("value"), "hello\n\n> wor\n\nld."); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 12); }); - click('button.quote'); + click("button.quote"); andThen(() => { - assert.equal(this.get('value'), 'hello\n\nwor\n\nld.'); + assert.equal(this.get("value"), "hello\n\nwor\n\nld."); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 10); }); @@ -590,26 +641,25 @@ testCase('quote button', function(assert, textarea) { textarea.selectionEnd = 15; }); - click('button.quote'); + click("button.quote"); andThen(() => { - assert.equal(this.get('value'), 'hello\n\nwor\n\nld.\n\n> Blockquote'); + assert.equal(this.get("value"), "hello\n\nwor\n\nld.\n\n> Blockquote"); }); - }); testCase(`bullet button with no selection`, function(assert, textarea) { - const example = I18n.t('composer.list_item'); + const example = I18n.t("composer.list_item"); click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), `hello world.\n\n* ${example}`); + assert.equal(this.get("value"), `hello world.\n\n* ${example}`); assert.equal(textarea.selectionStart, 14); assert.equal(textarea.selectionEnd, 16 + example.length); }); click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), `hello world.\n\n${example}`); + assert.equal(this.get("value"), `hello world.\n\n${example}`); }); }); @@ -619,21 +669,24 @@ testCase(`bullet button with a selection`, function(assert, textarea) { click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), `hello\n\n* world\n\n.`); + assert.equal(this.get("value"), `hello\n\n* world\n\n.`); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 14); }); click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), `hello\n\nworld\n\n.`); + assert.equal(this.get("value"), `hello\n\nworld\n\n.`); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 12); }); }); -testCase(`bullet button with a multiple line selection`, function(assert, textarea) { - this.set('value', "* Hello\n\nWorld\n\nEvil"); +testCase(`bullet button with a multiple line selection`, function( + assert, + textarea +) { + this.set("value", "* Hello\n\nWorld\n\nEvil"); andThen(() => { textarea.selectionStart = 0; @@ -642,32 +695,32 @@ testCase(`bullet button with a multiple line selection`, function(assert, textar click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), "Hello\n\nWorld\n\nEvil"); + assert.equal(this.get("value"), "Hello\n\nWorld\n\nEvil"); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 18); }); click(`button.bullet`); andThen(() => { - assert.equal(this.get('value'), "* Hello\n\n* World\n\n* Evil"); + assert.equal(this.get("value"), "* Hello\n\n* World\n\n* Evil"); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 24); }); }); testCase(`list button with no selection`, function(assert, textarea) { - const example = I18n.t('composer.list_item'); + const example = I18n.t("composer.list_item"); click(`button.list`); andThen(() => { - assert.equal(this.get('value'), `hello world.\n\n1. ${example}`); + assert.equal(this.get("value"), `hello world.\n\n1. ${example}`); assert.equal(textarea.selectionStart, 14); assert.equal(textarea.selectionEnd, 17 + example.length); }); click(`button.list`); andThen(() => { - assert.equal(this.get('value'), `hello world.\n\n${example}`); + assert.equal(this.get("value"), `hello world.\n\n${example}`); assert.equal(textarea.selectionStart, 14); assert.equal(textarea.selectionEnd, 14 + example.length); }); @@ -679,21 +732,21 @@ testCase(`list button with a selection`, function(assert, textarea) { click(`button.list`); andThen(() => { - assert.equal(this.get('value'), `hello\n\n1. world\n\n.`); + assert.equal(this.get("value"), `hello\n\n1. world\n\n.`); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 15); }); click(`button.list`); andThen(() => { - assert.equal(this.get('value'), `hello\n\nworld\n\n.`); + assert.equal(this.get("value"), `hello\n\nworld\n\n.`); assert.equal(textarea.selectionStart, 7); assert.equal(textarea.selectionEnd, 12); }); }); testCase(`list button with line sequence`, function(assert, textarea) { - this.set('value', "Hello\n\nWorld\n\nEvil"); + this.set("value", "Hello\n\nWorld\n\nEvil"); andThen(() => { textarea.selectionStart = 0; @@ -702,46 +755,45 @@ testCase(`list button with line sequence`, function(assert, textarea) { click(`button.list`); andThen(() => { - assert.equal(this.get('value'), "1. Hello\n\n2. World\n\n3. Evil"); + assert.equal(this.get("value"), "1. Hello\n\n2. World\n\n3. Evil"); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 27); }); click(`button.list`); andThen(() => { - assert.equal(this.get('value'), "Hello\n\nWorld\n\nEvil"); + assert.equal(this.get("value"), "Hello\n\nWorld\n\nEvil"); assert.equal(textarea.selectionStart, 0); assert.equal(textarea.selectionEnd, 18); }); }); -componentTest('clicking the toggle-direction button toggles the direction', { - template: '{{d-editor value=value}}', +componentTest("clicking the toggle-direction button toggles the direction", { + template: "{{d-editor value=value}}", beforeEach() { this.siteSettings.support_mixed_text_direction = true; this.siteSettings.default_locale = "en"; }, test(assert) { - const textarea = this.$('textarea.d-editor-input'); - click('button.toggle-direction'); + const textarea = this.$("textarea.d-editor-input"); + click("button.toggle-direction"); andThen(() => { - assert.equal(textarea.attr('dir'), 'rtl'); + assert.equal(textarea.attr("dir"), "rtl"); }); - click('button.toggle-direction'); + click("button.toggle-direction"); andThen(() => { - assert.equal(textarea.attr('dir'), 'ltr'); + assert.equal(textarea.attr("dir"), "ltr"); }); } }); testCase(`doesn't jump to bottom with long text`, function(assert, textarea) { - - let longText = 'hello world.'; - for (let i=0; i<8; i++) { + let longText = "hello world."; + for (let i = 0; i < 8; i++) { longText = longText + longText; } - this.set('value', longText); + this.set("value", longText); andThen(() => { $(textarea).scrollTop(0); @@ -749,110 +801,127 @@ testCase(`doesn't jump to bottom with long text`, function(assert, textarea) { textarea.selectionEnd = 3; }); - click('button.bold'); + click("button.bold"); andThen(() => { - assert.equal($(textarea).scrollTop(), 0, 'it stays scrolled up'); + assert.equal($(textarea).scrollTop(), 0, "it stays scrolled up"); }); }); -componentTest('emoji', { - template: '{{d-editor value=value}}', +componentTest("emoji", { + template: "{{d-editor value=value}}", beforeEach() { // Test adding a custom button - withPluginApi('0.1', api => { + withPluginApi("0.1", api => { api.onToolbarCreate(toolbar => { toolbar.addButton({ - id: 'emoji', - group: 'extras', - icon: 'smile-o', - action: 'emoji' + id: "emoji", + group: "extras", + icon: "smile-o", + action: "emoji" }); }); }); - this.set('value', 'hello world.'); + this.set("value", "hello world."); }, test(assert) { - jumpEnd(this.$('textarea.d-editor-input')[0]); - click('button.emoji'); + jumpEnd(this.$("textarea.d-editor-input")[0]); + click("button.emoji"); - click('.emoji-picker .section[data-section="people"] button.emoji[title="grinning"]'); + click( + '.emoji-picker .section[data-section="people"] button.emoji[title="grinning"]' + ); andThen(() => { - assert.equal(this.get('value'), 'hello world.:grinning:'); + assert.equal(this.get("value"), "hello world.:grinning:"); }); } }); testCase("replace-text event by default", function(assert) { - this.set('value', "red green blue"); + this.set("value", "red green blue"); andThen(() => { - this.container.lookup('app-events:main').trigger('composer:replace-text', 'green', 'yellow'); + this.container + .lookup("app-events:main") + .trigger("composer:replace-text", "green", "yellow"); }); andThen(() => { - assert.equal(this.get('value'), 'red green blue'); + assert.equal(this.get("value"), "red green blue"); }); }); composerTestCase("replace-text event for composer", function(assert) { - this.set('value', "red green blue"); + this.set("value", "red green blue"); andThen(() => { - this.container.lookup('app-events:main').trigger('composer:replace-text', 'green', 'yellow'); + this.container + .lookup("app-events:main") + .trigger("composer:replace-text", "green", "yellow"); }); andThen(() => { - assert.equal(this.get('value'), 'red yellow blue'); + assert.equal(this.get("value"), "red yellow blue"); }); }); - (() => { // Tests to check cursor/selection after replace-text event. - const BEFORE = 'red green blue'; - const NEEDLE = 'green'; - const REPLACE = 'yellow'; + const BEFORE = "red green blue"; + const NEEDLE = "green"; + const REPLACE = "yellow"; const AFTER = BEFORE.replace(NEEDLE, REPLACE); const CASES = [ { - description: 'cursor at start remains there', + description: "cursor at start remains there", before: [0, 0], after: [0, 0] - },{ - description: 'cursor before needle becomes cursor before replacement', + }, + { + description: "cursor before needle becomes cursor before replacement", before: [BEFORE.indexOf(NEEDLE), 0], after: [AFTER.indexOf(REPLACE), 0] - },{ - description: 'cursor at needle start + 1 moves behind replacement', + }, + { + description: "cursor at needle start + 1 moves behind replacement", before: [BEFORE.indexOf(NEEDLE) + 1, 0], after: [AFTER.indexOf(REPLACE) + REPLACE.length, 0] - },{ - description: 'cursor at needle end - 1 stays behind replacement', + }, + { + description: "cursor at needle end - 1 stays behind replacement", before: [BEFORE.indexOf(NEEDLE) + NEEDLE.length - 1, 0], after: [AFTER.indexOf(REPLACE) + REPLACE.length, 0] - },{ - description: 'cursor behind needle becomes cursor behind replacement', + }, + { + description: "cursor behind needle becomes cursor behind replacement", before: [BEFORE.indexOf(NEEDLE) + NEEDLE.length, 0], after: [AFTER.indexOf(REPLACE) + REPLACE.length, 0] - },{ - description: 'cursor at end remains there', + }, + { + description: "cursor at end remains there", before: [BEFORE.length, 0], after: [AFTER.length, 0] - },{ - description: 'selection spanning needle start becomes selection until replacement start', + }, + { + description: + "selection spanning needle start becomes selection until replacement start", before: [BEFORE.indexOf(NEEDLE) - 1, 2], after: [AFTER.indexOf(REPLACE) - 1, 1] - },{ - description: 'selection spanning needle end becomes selection from replacement end', + }, + { + description: + "selection spanning needle end becomes selection from replacement end", before: [BEFORE.indexOf(NEEDLE) + NEEDLE.length - 1, 2], after: [AFTER.indexOf(REPLACE) + REPLACE.length, 1] - },{ - description: 'selection spanning needle becomes selection spanning replacement', + }, + { + description: + "selection spanning needle becomes selection spanning replacement", before: [BEFORE.indexOf(NEEDLE) - 1, NEEDLE.length + 2], after: [AFTER.indexOf(REPLACE) - 1, REPLACE.length + 2] - },{ - description: 'complete selection remains complete', + }, + { + description: "complete selection remains complete", before: [0, BEFORE.length], after: [0, AFTER.length] } @@ -873,25 +942,33 @@ composerTestCase("replace-text event for composer", function(assert) { return [ '"', text.substr(0, start), - '<', + "<", text.substr(start, len), - '>', - text.substr(start+len), - '"', - ].join(''); + ">", + text.substr(start + len), + '"' + ].join(""); } for (let i = 0; i < CASES.length; i++) { const CASE = CASES[i]; - composerTestCase(`replace-text event: ${CASE.description}`, function(assert, textarea) { - this.set('value', BEFORE); + composerTestCase(`replace-text event: ${CASE.description}`, function( + assert, + textarea + ) { + this.set("value", BEFORE); setSelection(textarea, CASE.before); andThen(() => { - this.container.lookup('app-events:main').trigger('composer:replace-text', 'green', 'yellow'); + this.container + .lookup("app-events:main") + .trigger("composer:replace-text", "green", "yellow"); }); andThen(() => { let expect = formatTextWithSelection(AFTER, CASE.after); - let actual = formatTextWithSelection(this.get('value'), getSelection(textarea)); + let actual = formatTextWithSelection( + this.get("value"), + getSelection(textarea) + ); assert.equal(actual, expect); }); }); diff --git a/test/javascripts/components/d-icon-test.js.es6 b/test/javascripts/components/d-icon-test.js.es6 index d4f3d489aa5..bcaca7f7533 100644 --- a/test/javascripts/components/d-icon-test.js.es6 +++ b/test/javascripts/components/d-icon-test.js.es6 @@ -1,21 +1,28 @@ -import componentTest from 'helpers/component-test'; +import componentTest from "helpers/component-test"; -moduleForComponent('d-icon', {integration: true}); +moduleForComponent("d-icon", { integration: true }); -componentTest('default', { +componentTest("default", { template: '{{d-icon "bars"}}', test(assert) { - const html = this.$().html().trim(); + const html = this.$() + .html() + .trim(); assert.equal(html, ''); } }); -componentTest('with replacement', { +componentTest("with replacement", { template: '{{d-icon "d-watching"}}', test(assert) { - const html = this.$().html().trim(); - assert.equal(html, ''); + const html = this.$() + .html() + .trim(); + assert.equal( + html, + '' + ); } }); diff --git a/test/javascripts/components/group-membership-button-test.js.es6 b/test/javascripts/components/group-membership-button-test.js.es6 index a321d7ed4f8..1c468551506 100644 --- a/test/javascripts/components/group-membership-button-test.js.es6 +++ b/test/javascripts/components/group-membership-button-test.js.es6 @@ -1,67 +1,73 @@ -moduleFor('component:group-membership-button'); +moduleFor("component:group-membership-button"); -QUnit.test('canJoinGroup', function(assert) { +QUnit.test("canJoinGroup", function(assert) { this.subject().setProperties({ model: { public_admission: false, is_group_user: true } }); assert.equal( - this.subject().get("canJoinGroup"), false, + this.subject().get("canJoinGroup"), + false, "can't join group if public_admission is false" ); this.subject().set("model.public_admission", true); assert.equal( - this.subject().get("canJoinGroup"), false, + this.subject().get("canJoinGroup"), + false, "can't join group if user is already in the group" ); this.subject().set("model.is_group_user", false); assert.equal( - this.subject().get("canJoinGroup"), true, + this.subject().get("canJoinGroup"), + true, "allowed to join group" ); }); -QUnit.test('canLeaveGroup', function(assert) { +QUnit.test("canLeaveGroup", function(assert) { this.subject().setProperties({ model: { public_exit: false, is_group_user: false } }); assert.equal( - this.subject().get("canLeaveGroup"), false, + this.subject().get("canLeaveGroup"), + false, "can't leave group if public_exit is false" ); this.subject().set("model.public_exit", true); assert.equal( - this.subject().get("canLeaveGroup"), false, + this.subject().get("canLeaveGroup"), + false, "can't leave group if user is not in the group" ); this.subject().set("model.is_group_user", true); assert.equal( - this.subject().get("canLeaveGroup"), true, + this.subject().get("canLeaveGroup"), + true, "allowed to leave group" ); }); -QUnit.test('userIsGroupUser', function(assert) { +QUnit.test("userIsGroupUser", function(assert) { this.subject().setProperties({ model: { is_group_user: true } }); - assert.equal(this.subject().get('userIsGroupUser'), true); + assert.equal(this.subject().get("userIsGroupUser"), true); - this.subject().set('model.is_group_user', false); + this.subject().set("model.is_group_user", false); - assert.equal(this.subject().get('userIsGroupUser'), false); + assert.equal(this.subject().get("userIsGroupUser"), false); - this.subject().set('model.is_group_user', null); + this.subject().set("model.is_group_user", null); - assert.equal(this.subject().get('userIsGroupUser'), false); + assert.equal(this.subject().get("userIsGroupUser"), false); }); diff --git a/test/javascripts/components/keyboard-shortcuts-test.js.es6 b/test/javascripts/components/keyboard-shortcuts-test.js.es6 index 642f35d5432..d127c89fa6b 100644 --- a/test/javascripts/components/keyboard-shortcuts-test.js.es6 +++ b/test/javascripts/components/keyboard-shortcuts-test.js.es6 @@ -1,7 +1,7 @@ -import DiscourseURL from 'discourse/lib/url'; +import DiscourseURL from "discourse/lib/url"; var testMouseTrap; -import KeyboardShortcuts from 'discourse/lib/keyboard-shortcuts'; +import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts"; QUnit.module("lib:keyboard-shortcuts", { beforeEach() { @@ -15,8 +15,7 @@ QUnit.module("lib:keyboard-shortcuts", { if (_.isArray(bindings)) { _.each(bindings, registerBinding, this); - } - else { + } else { registerBinding(bindings); } }, @@ -28,38 +27,39 @@ QUnit.module("lib:keyboard-shortcuts", { sandbox.stub(DiscourseURL, "routeTo"); - $("#qunit-fixture").html([ - "", - " ", - " |
", + " ", + " |
I don't know how to pronounce that in English, but this makes me think of the French word \"disquette\" (floppy disk)
", - "created_at":"2015-01-23T15:13:01.935Z", - "title":"Consistent new indicator", - "url":"/t/consistent-new-indicator/24355/1", - "user_title":"designerator", - "user_long_name":"", - "category":{ - "id":9, - "name":"ux", - "color":"5F497A", - "topic_id":2628, - "topic_count":540, - "created_at":"2013-02-10T03:52:21.322Z", - "updated_at":"2015-01-22T18:05:32.152Z", - "user_id":32, - "topics_year":370, - "topics_month":33, - "topics_week":3, - "slug":"ux", - "description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":5823, - "latest_post_id":94610, - "latest_topic_id":24355, - "position":25, - "parent_category_id":null, - "posts_year":4264, - "posts_month":609, - "posts_week":103, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":28, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"ux", - "auto_close_based_on_last_post":false + id: 94607, + cooked: + 'I don\'t know how to pronounce that in English, but this makes me think of the French word "disquette" (floppy disk)
', + created_at: "2015-01-23T15:13:01.935Z", + title: "Consistent new indicator", + url: "/t/consistent-new-indicator/24355/1", + user_title: "designerator", + user_long_name: "", + category: { + id: 9, + name: "ux", + color: "5F497A", + topic_id: 2628, + topic_count: 540, + created_at: "2013-02-10T03:52:21.322Z", + updated_at: "2015-01-22T18:05:32.152Z", + user_id: 32, + topics_year: 370, + topics_month: 33, + topics_week: 3, + slug: "ux", + description: + "Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 5823, + latest_post_id: 94610, + latest_topic_id: 24355, + position: 25, + parent_category_id: null, + posts_year: 4264, + posts_month: 609, + posts_week: 103, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 28, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "ux", + auto_close_based_on_last_post: false }, - "user":{ - "id":2770, - "username":"awesomerobot", - "uploaded_avatar_id":33872, - "avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png" + user: { + id: 2770, + username: "awesomerobot", + uploaded_avatar_id: 33872, + avatar_template: + "/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png" } }, { - "id":94603, - "cooked":"Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", - "created_at":"2015-01-23T14:59:21.941Z", - "title":"The end of Clown Vomit, or, simplified category styles", - "url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/63", - "user_title":"designerator", - "user_long_name":"", - "category":{ - "id":9, - "name":"ux", - "color":"5F497A", - "topic_id":2628, - "topic_count":540, - "created_at":"2013-02-10T03:52:21.322Z", - "updated_at":"2015-01-22T18:05:32.152Z", - "user_id":32, - "topics_year":370, - "topics_month":33, - "topics_week":3, - "slug":"ux", - "description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":5823, - "latest_post_id":94610, - "latest_topic_id":24355, - "position":25, - "parent_category_id":null, - "posts_year":4264, - "posts_month":609, - "posts_week":103, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":28, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"ux", - "auto_close_based_on_last_post":false + id: 94603, + cooked: + "Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", + created_at: "2015-01-23T14:59:21.941Z", + title: "The end of Clown Vomit, or, simplified category styles", + url: "/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/63", + user_title: "designerator", + user_long_name: "", + category: { + id: 9, + name: "ux", + color: "5F497A", + topic_id: 2628, + topic_count: 540, + created_at: "2013-02-10T03:52:21.322Z", + updated_at: "2015-01-22T18:05:32.152Z", + user_id: 32, + topics_year: 370, + topics_month: 33, + topics_week: 3, + slug: "ux", + description: + "Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 5823, + latest_post_id: 94610, + latest_topic_id: 24355, + position: 25, + parent_category_id: null, + posts_year: 4264, + posts_month: 609, + posts_week: 103, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 28, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "ux", + auto_close_based_on_last_post: false }, - "user":{ - "id":2770, - "username":"awesomerobot", - "uploaded_avatar_id":33872, - "avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png" + user: { + id: 2770, + username: "awesomerobot", + uploaded_avatar_id: 33872, + avatar_template: + "/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png" } }, { - "id":94601, - "cooked":"Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", - "created_at":"2015-01-23T14:51:55.497Z", - "title":"The end of Clown Vomit, or, simplified category styles", - "url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/62", - "user_title":"designerator", - "user_long_name":"", - "category":{ - "id":9, - "name":"ux", - "color":"5F497A", - "topic_id":2628, - "topic_count":540, - "created_at":"2013-02-10T03:52:21.322Z", - "updated_at":"2015-01-22T18:05:32.152Z", - "user_id":32, - "topics_year":370, - "topics_month":33, - "topics_week":3, - "slug":"ux", - "description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":5823, - "latest_post_id":94610, - "latest_topic_id":24355, - "position":25, - "parent_category_id":null, - "posts_year":4264, - "posts_month":609, - "posts_week":103, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":28, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"ux", - "auto_close_based_on_last_post":false + id: 94601, + cooked: + "Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", + created_at: "2015-01-23T14:51:55.497Z", + title: "The end of Clown Vomit, or, simplified category styles", + url: "/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/62", + user_title: "designerator", + user_long_name: "", + category: { + id: 9, + name: "ux", + color: "5F497A", + topic_id: 2628, + topic_count: 540, + created_at: "2013-02-10T03:52:21.322Z", + updated_at: "2015-01-22T18:05:32.152Z", + user_id: 32, + topics_year: 370, + topics_month: 33, + topics_week: 3, + slug: "ux", + description: + "Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 5823, + latest_post_id: 94610, + latest_topic_id: 24355, + position: 25, + parent_category_id: null, + posts_year: 4264, + posts_month: 609, + posts_week: 103, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 28, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "ux", + auto_close_based_on_last_post: false }, - "user":{ - "id":2770, - "username":"awesomerobot", - "uploaded_avatar_id":33872, - "avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png" + user: { + id: 2770, + username: "awesomerobot", + uploaded_avatar_id: 33872, + avatar_template: + "/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png" } }, { - "id":94577, - "cooked":"Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", - "created_at":"2015-01-23T10:50:55.846Z", - "title":"Quote reply insertion at cursor position", - "url":"/t/quote-reply-insertion-at-cursor-position/24344/4", - "user_title":"team", - "user_long_name":"Régis Hanol", - "category":{ - "id":2, - "name":"feature", - "color":"0E76BD", - "topic_id":11, - "topic_count":1592, - "created_at":"2013-02-02T21:42:52.552Z", - "updated_at":"2015-01-22T18:05:32.647Z", - "user_id":1, - "topics_year":919, - "topics_month":60, - "topics_week":20, - "slug":"feature", - "description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":14360, - "latest_post_id":94600, - "latest_topic_id":24344, - "position":25, - "parent_category_id":null, - "posts_year":8617, - "posts_month":690, - "posts_week":190, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":2, - "posts_day":8, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"feature", - "auto_close_based_on_last_post":false + id: 94577, + cooked: + "Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", + created_at: "2015-01-23T10:50:55.846Z", + title: "Quote reply insertion at cursor position", + url: "/t/quote-reply-insertion-at-cursor-position/24344/4", + user_title: "team", + user_long_name: "Régis Hanol", + category: { + id: 2, + name: "feature", + color: "0E76BD", + topic_id: 11, + topic_count: 1592, + created_at: "2013-02-02T21:42:52.552Z", + updated_at: "2015-01-22T18:05:32.647Z", + user_id: 1, + topics_year: 919, + topics_month: 60, + topics_week: 20, + slug: "feature", + description: + "Discussion about features or potential features of Discourse: how they work, why they work, etc.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 14360, + latest_post_id: 94600, + latest_topic_id: 24344, + position: 25, + parent_category_id: null, + posts_year: 8617, + posts_month: 690, + posts_week: 190, + email_in: null, + email_in_allow_strangers: false, + topics_day: 2, + posts_day: 8, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "feature", + auto_close_based_on_last_post: false }, - "user":{ - "id":1995, - "username":"zogstrip", - "uploaded_avatar_id":8630, - "avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" + user: { + id: 1995, + username: "zogstrip", + uploaded_avatar_id: 8630, + avatar_template: + "/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" } }, { - "id":94574, - "cooked":"Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", - "created_at":"2015-01-23T10:31:29.222Z", - "title":"Quote reply insertion at cursor position", - "url":"/t/quote-reply-insertion-at-cursor-position/24344/2", - "user_title":"team", - "user_long_name":"Régis Hanol", - "category":{ - "id":2, - "name":"feature", - "color":"0E76BD", - "topic_id":11, - "topic_count":1592, - "created_at":"2013-02-02T21:42:52.552Z", - "updated_at":"2015-01-22T18:05:32.647Z", - "user_id":1, - "topics_year":919, - "topics_month":60, - "topics_week":20, - "slug":"feature", - "description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":14360, - "latest_post_id":94600, - "latest_topic_id":24344, - "position":25, - "parent_category_id":null, - "posts_year":8617, - "posts_month":690, - "posts_week":190, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":2, - "posts_day":8, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"feature", - "auto_close_based_on_last_post":false + id: 94574, + cooked: + "Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", + created_at: "2015-01-23T10:31:29.222Z", + title: "Quote reply insertion at cursor position", + url: "/t/quote-reply-insertion-at-cursor-position/24344/2", + user_title: "team", + user_long_name: "Régis Hanol", + category: { + id: 2, + name: "feature", + color: "0E76BD", + topic_id: 11, + topic_count: 1592, + created_at: "2013-02-02T21:42:52.552Z", + updated_at: "2015-01-22T18:05:32.647Z", + user_id: 1, + topics_year: 919, + topics_month: 60, + topics_week: 20, + slug: "feature", + description: + "Discussion about features or potential features of Discourse: how they work, why they work, etc.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 14360, + latest_post_id: 94600, + latest_topic_id: 24344, + position: 25, + parent_category_id: null, + posts_year: 8617, + posts_month: 690, + posts_week: 190, + email_in: null, + email_in_allow_strangers: false, + topics_day: 2, + posts_day: 8, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "feature", + auto_close_based_on_last_post: false }, - "user":{ - "id":1995, - "username":"zogstrip", - "uploaded_avatar_id":8630, - "avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" + user: { + id: 1995, + username: "zogstrip", + uploaded_avatar_id: 8630, + avatar_template: + "/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" } }, { - "id":94572, - "cooked":"Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", - "created_at":"2015-01-23T09:46:00.901Z", - "title":"Translations frequently broken", - "url":"/t/translations-frequently-broken/22546/27", - "user_title":"team", - "user_long_name":"Régis Hanol", - "category":{ - "id":27, - "name":"translations", - "color":"808281", - "topic_id":14549, - "topic_count":146, - "created_at":"2014-04-07T20:30:17.623Z", - "updated_at":"2015-01-22T18:05:33.111Z", - "user_id":2, - "topics_year":134, - "topics_month":5, - "topics_week":3, - "slug":"translations", - "description":"This category is for discussion about localizing Discourse.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":1167, - "latest_post_id":94575, - "latest_topic_id":24301, - "position":25, - "parent_category_id":7, - "posts_year":965, - "posts_month":60, - "posts_week":29, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":1, - "posts_day":5, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"translations", - "auto_close_based_on_last_post":false + id: 94572, + cooked: + "Agree that the markup isn't ideal - it's kind of hacked together at the moment; especially because we have two different styles. I think once we settle on the specifics it can be re-written entirely.
", + created_at: "2015-01-23T09:46:00.901Z", + title: "Translations frequently broken", + url: "/t/translations-frequently-broken/22546/27", + user_title: "team", + user_long_name: "Régis Hanol", + category: { + id: 27, + name: "translations", + color: "808281", + topic_id: 14549, + topic_count: 146, + created_at: "2014-04-07T20:30:17.623Z", + updated_at: "2015-01-22T18:05:33.111Z", + user_id: 2, + topics_year: 134, + topics_month: 5, + topics_week: 3, + slug: "translations", + description: + "This category is for discussion about localizing Discourse.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 1167, + latest_post_id: 94575, + latest_topic_id: 24301, + position: 25, + parent_category_id: 7, + posts_year: 965, + posts_month: 60, + posts_week: 29, + email_in: null, + email_in_allow_strangers: false, + topics_day: 1, + posts_day: 5, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "translations", + auto_close_based_on_last_post: false }, - "user":{ - "id":1995, - "username":"zogstrip", - "uploaded_avatar_id":8630, - "avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" + user: { + id: 1995, + username: "zogstrip", + uploaded_avatar_id: 8630, + avatar_template: + "/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" } }, { - "id":94555, - "cooked":"I don't know how to pronounce that in English, but this makes me think of the French word \"disquette\" (floppy disk)
", - "created_at":"2015-01-23T08:17:31.700Z", - "title":"Introducing Discette - a minimal ember-cli front end to Discourse", - "url":"/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/3", - "user_title":"team", - "user_long_name":"Régis Hanol", - "category":{ - "id":7, - "name":"dev", - "color":"000", - "topic_id":1026, - "topic_count":574, - "created_at":"2013-02-06T08:43:41.550Z", - "updated_at":"2015-01-22T18:05:32.855Z", - "user_id":32, - "topics_year":298, - "topics_month":29, - "topics_week":2, - "slug":"dev", - "description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":4196, - "latest_post_id":94590, - "latest_topic_id":24349, - "position":25, - "parent_category_id":null, - "posts_year":2095, - "posts_month":172, - "posts_week":16, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":3, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"dev", - "auto_close_based_on_last_post":false + id: 94555, + cooked: + 'I don\'t know how to pronounce that in English, but this makes me think of the French word "disquette" (floppy disk)
', + created_at: "2015-01-23T08:17:31.700Z", + title: + "Introducing Discette - a minimal ember-cli front end to Discourse", + url: + "/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/3", + user_title: "team", + user_long_name: "Régis Hanol", + category: { + id: 7, + name: "dev", + color: "000", + topic_id: 1026, + topic_count: 574, + created_at: "2013-02-06T08:43:41.550Z", + updated_at: "2015-01-22T18:05:32.855Z", + user_id: 32, + topics_year: 298, + topics_month: 29, + topics_week: 2, + slug: "dev", + description: + "This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 4196, + latest_post_id: 94590, + latest_topic_id: 24349, + position: 25, + parent_category_id: null, + posts_year: 2095, + posts_month: 172, + posts_week: 16, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 3, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "dev", + auto_close_based_on_last_post: false }, - "user":{ - "id":1995, - "username":"zogstrip", - "uploaded_avatar_id":8630, - "avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" + user: { + id: 1995, + username: "zogstrip", + uploaded_avatar_id: 8630, + avatar_template: + "/user_avatar/meta.discourse.org/zogstrip/{size}/8630.png" } }, { - "id":94544, - "cooked":"@techapj fixed this for 1.2.
", - "created_at":"2015-01-23T05:49:35.881Z", - "title":"After sign-in, I'm not redirected to the conversation", - "url":"/t/after-sign-in-im-not-redirected-to-the-conversation/17753/8", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":9, - "name":"ux", - "color":"5F497A", - "topic_id":2628, - "topic_count":540, - "created_at":"2013-02-10T03:52:21.322Z", - "updated_at":"2015-01-22T18:05:32.152Z", - "user_id":32, - "topics_year":370, - "topics_month":33, - "topics_week":3, - "slug":"ux", - "description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":5823, - "latest_post_id":94610, - "latest_topic_id":24355, - "position":25, - "parent_category_id":null, - "posts_year":4264, - "posts_month":609, - "posts_week":103, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":28, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"ux", - "auto_close_based_on_last_post":false + id: 94544, + cooked: + '@techapj fixed this for 1.2.
', + created_at: "2015-01-23T05:49:35.881Z", + title: "After sign-in, I'm not redirected to the conversation", + url: "/t/after-sign-in-im-not-redirected-to-the-conversation/17753/8", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 9, + name: "ux", + color: "5F497A", + topic_id: 2628, + topic_count: 540, + created_at: "2013-02-10T03:52:21.322Z", + updated_at: "2015-01-22T18:05:32.152Z", + user_id: 32, + topics_year: 370, + topics_month: 33, + topics_week: 3, + slug: "ux", + description: + "Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 5823, + latest_post_id: 94610, + latest_topic_id: 24355, + position: 25, + parent_category_id: null, + posts_year: 4264, + posts_month: 609, + posts_week: 103, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 28, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "ux", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94543, - "cooked":"Oh yes IOS 8.2 -- well, let's see what happens because there is really no fix on our end. Basic HTML / CSS stuff is broken.
", - "created_at":"2015-01-23T05:45:40.306Z", - "title":"Dealing with iOS 8 Mobile Safari bugs?", - "url":"/t/dealing-with-ios-8-mobile-safari-bugs/24101/7", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":2, - "name":"feature", - "color":"0E76BD", - "topic_id":11, - "topic_count":1592, - "created_at":"2013-02-02T21:42:52.552Z", - "updated_at":"2015-01-22T18:05:32.647Z", - "user_id":1, - "topics_year":919, - "topics_month":60, - "topics_week":20, - "slug":"feature", - "description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":14360, - "latest_post_id":94600, - "latest_topic_id":24344, - "position":25, - "parent_category_id":null, - "posts_year":8617, - "posts_month":690, - "posts_week":190, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":2, - "posts_day":8, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"feature", - "auto_close_based_on_last_post":false + id: 94543, + cooked: + "Oh yes IOS 8.2 -- well, let's see what happens because there is really no fix on our end. Basic HTML / CSS stuff is broken.
", + created_at: "2015-01-23T05:45:40.306Z", + title: "Dealing with iOS 8 Mobile Safari bugs?", + url: "/t/dealing-with-ios-8-mobile-safari-bugs/24101/7", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 2, + name: "feature", + color: "0E76BD", + topic_id: 11, + topic_count: 1592, + created_at: "2013-02-02T21:42:52.552Z", + updated_at: "2015-01-22T18:05:32.647Z", + user_id: 1, + topics_year: 919, + topics_month: 60, + topics_week: 20, + slug: "feature", + description: + "Discussion about features or potential features of Discourse: how they work, why they work, etc.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 14360, + latest_post_id: 94600, + latest_topic_id: 24344, + position: 25, + parent_category_id: null, + posts_year: 8617, + posts_month: 690, + posts_week: 190, + email_in: null, + email_in_allow_strangers: false, + topics_day: 2, + posts_day: 8, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "feature", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94542, - "cooked":"Hmm that looks like a bug, @techapj can you have a look?
", - "created_at":"2015-01-23T05:43:55.602Z", - "title":"RSS is not valid", - "url":"/t/rss-is-not-valid/24338/2", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":6, - "name":"support", - "color":"CEA9A9", - "topic_id":389, - "topic_count":1781, - "created_at":"2013-02-05T22:16:38.672Z", - "updated_at":"2015-01-22T18:05:33.572Z", - "user_id":1, - "topics_year":1541, - "topics_month":167, - "topics_week":49, - "slug":"support", - "description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":12272, - "latest_post_id":94602, - "latest_topic_id":24346, - "position":25, - "parent_category_id":null, - "posts_year":10571, - "posts_month":1254, - "posts_week":413, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":5, - "posts_day":70, - "logo_url":"", - "background_url":"", - "allow_badges":true, - "name_lower":"support", - "auto_close_based_on_last_post":false + id: 94542, + cooked: + 'Hmm that looks like a bug, @techapj can you have a look?
', + created_at: "2015-01-23T05:43:55.602Z", + title: "RSS is not valid", + url: "/t/rss-is-not-valid/24338/2", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 6, + name: "support", + color: "CEA9A9", + topic_id: 389, + topic_count: 1781, + created_at: "2013-02-05T22:16:38.672Z", + updated_at: "2015-01-22T18:05:33.572Z", + user_id: 1, + topics_year: 1541, + topics_month: 167, + topics_week: 49, + slug: "support", + description: + "Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 12272, + latest_post_id: 94602, + latest_topic_id: 24346, + position: 25, + parent_category_id: null, + posts_year: 10571, + posts_month: 1254, + posts_week: 413, + email_in: null, + email_in_allow_strangers: false, + topics_day: 5, + posts_day: 70, + logo_url: "", + background_url: "", + allow_badges: true, + name_lower: "support", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94522, - "cooked":"Oh I see. @zogstrip can you have a look?
", - "created_at":"2015-01-23T03:00:20.485Z", - "title":"Pasted image upload size error", - "url":"/t/pasted-image-upload-size-error/24320/4", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":1, - "name":"bug", - "color":"e9dd00", - "topic_id":2, - "topic_count":1729, - "created_at":"2013-02-01T04:56:34.914Z", - "updated_at":"2015-01-22T18:05:33.426Z", - "user_id":1, - "topics_year":1114, - "topics_month":69, - "topics_week":22, - "slug":"bug", - "description":"A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.", - "text_color":"000000", - "read_restricted":false, - "auto_close_hours":null, - "post_count":11179, - "latest_post_id":94611, - "latest_topic_id":24350, - "position":25, - "parent_category_id":null, - "posts_year":7138, - "posts_month":397, - "posts_week":121, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":1, - "posts_day":6, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"bug", - "auto_close_based_on_last_post":false + id: 94522, + cooked: + 'Oh I see. @zogstrip can you have a look?
', + created_at: "2015-01-23T03:00:20.485Z", + title: "Pasted image upload size error", + url: "/t/pasted-image-upload-size-error/24320/4", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 1, + name: "bug", + color: "e9dd00", + topic_id: 2, + topic_count: 1729, + created_at: "2013-02-01T04:56:34.914Z", + updated_at: "2015-01-22T18:05:33.426Z", + user_id: 1, + topics_year: 1114, + topics_month: 69, + topics_week: 22, + slug: "bug", + description: + "A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.", + text_color: "000000", + read_restricted: false, + auto_close_hours: null, + post_count: 11179, + latest_post_id: 94611, + latest_topic_id: 24350, + position: 25, + parent_category_id: null, + posts_year: 7138, + posts_month: 397, + posts_week: 121, + email_in: null, + email_in_allow_strangers: false, + topics_day: 1, + posts_day: 6, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "bug", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94521, - "cooked":"@techapj fixed this for 1.2.
", - "created_at":"2015-01-23T02:58:27.451Z", - "title":"The end of Clown Vomit, or, simplified category styles", - "url":"/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/57", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":9, - "name":"ux", - "color":"5F497A", - "topic_id":2628, - "topic_count":540, - "created_at":"2013-02-10T03:52:21.322Z", - "updated_at":"2015-01-22T18:05:32.152Z", - "user_id":32, - "topics_year":370, - "topics_month":33, - "topics_week":3, - "slug":"ux", - "description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":5823, - "latest_post_id":94610, - "latest_topic_id":24355, - "position":25, - "parent_category_id":null, - "posts_year":4264, - "posts_month":609, - "posts_week":103, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":28, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"ux", - "auto_close_based_on_last_post":false + id: 94521, + cooked: + '@techapj fixed this for 1.2.
', + created_at: "2015-01-23T02:58:27.451Z", + title: "The end of Clown Vomit, or, simplified category styles", + url: "/t/the-end-of-clown-vomit-or-simplified-category-styles/24249/57", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 9, + name: "ux", + color: "5F497A", + topic_id: 2628, + topic_count: 540, + created_at: "2013-02-10T03:52:21.322Z", + updated_at: "2015-01-22T18:05:32.152Z", + user_id: 32, + topics_year: 370, + topics_month: 33, + topics_week: 3, + slug: "ux", + description: + "Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 5823, + latest_post_id: 94610, + latest_topic_id: 24355, + position: 25, + parent_category_id: null, + posts_year: 4264, + posts_month: 609, + posts_week: 103, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 28, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "ux", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94519, - "cooked":"What would you suggest writing here that would be more clear?
", - "created_at":"2015-01-23T02:45:36.859Z", - "title":"What is \"Born mobile, born to touch\" supposed to tell me?", - "url":"/t/what-is-born-mobile-born-to-touch-supposed-to-tell-me/24329/3", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":3, - "name":"meta", - "color":"aaa", - "topic_id":24, - "topic_count":139, - "created_at":"2013-02-03T00:00:15.230Z", - "updated_at":"2015-01-22T18:05:32.797Z", - "user_id":1, - "topics_year":68, - "topics_month":5, - "topics_week":1, - "slug":"meta", - "description":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":1116, - "latest_post_id":94559, - "latest_topic_id":24208, - "position":25, - "parent_category_id":null, - "posts_year":553, - "posts_month":33, - "posts_week":8, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":0, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"meta", - "auto_close_based_on_last_post":false + id: 94519, + cooked: + "What would you suggest writing here that would be more clear?
", + created_at: "2015-01-23T02:45:36.859Z", + title: 'What is "Born mobile, born to touch" supposed to tell me?', + url: "/t/what-is-born-mobile-born-to-touch-supposed-to-tell-me/24329/3", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 3, + name: "meta", + color: "aaa", + topic_id: 24, + topic_count: 139, + created_at: "2013-02-03T00:00:15.230Z", + updated_at: "2015-01-22T18:05:32.797Z", + user_id: 1, + topics_year: 68, + topics_month: 5, + topics_week: 1, + slug: "meta", + description: + "Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 1116, + latest_post_id: 94559, + latest_topic_id: 24208, + position: 25, + parent_category_id: null, + posts_year: 553, + posts_month: 33, + posts_week: 8, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 0, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "meta", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94518, - "cooked":"You should generally create topics to host things like this, then make them wiki, close them, etc.
", - "created_at":"2015-01-23T02:42:20.053Z", - "title":"How to Create Static Pages in Discourse?", - "url":"/t/how-to-create-static-pages-in-discourse/24313/2", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":6, - "name":"support", - "color":"CEA9A9", - "topic_id":389, - "topic_count":1781, - "created_at":"2013-02-05T22:16:38.672Z", - "updated_at":"2015-01-22T18:05:33.572Z", - "user_id":1, - "topics_year":1541, - "topics_month":167, - "topics_week":49, - "slug":"support", - "description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":12272, - "latest_post_id":94602, - "latest_topic_id":24346, - "position":25, - "parent_category_id":null, - "posts_year":10571, - "posts_month":1254, - "posts_week":413, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":5, - "posts_day":70, - "logo_url":"", - "background_url":"", - "allow_badges":true, - "name_lower":"support", - "auto_close_based_on_last_post":false + id: 94518, + cooked: + "You should generally create topics to host things like this, then make them wiki, close them, etc.
", + created_at: "2015-01-23T02:42:20.053Z", + title: "How to Create Static Pages in Discourse?", + url: "/t/how-to-create-static-pages-in-discourse/24313/2", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 6, + name: "support", + color: "CEA9A9", + topic_id: 389, + topic_count: 1781, + created_at: "2013-02-05T22:16:38.672Z", + updated_at: "2015-01-22T18:05:33.572Z", + user_id: 1, + topics_year: 1541, + topics_month: 167, + topics_week: 49, + slug: "support", + description: + "Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 12272, + latest_post_id: 94602, + latest_topic_id: 24346, + position: 25, + parent_category_id: null, + posts_year: 10571, + posts_month: 1254, + posts_week: 413, + email_in: null, + email_in_allow_strangers: false, + topics_day: 5, + posts_day: 70, + logo_url: "", + background_url: "", + allow_badges: true, + name_lower: "support", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94517, - "cooked":"Doubtful this is a bug, probably dependent on the PNG encoding.
\n\nTry using PNGOUT, or converting to 8 bit PNGOUT, to see some of the differences. And PNGOUT is lossless!
", - "created_at":"2015-01-23T02:41:30.287Z", - "title":"Pasted image upload size error", - "url":"/t/pasted-image-upload-size-error/24320/2", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":1, - "name":"bug", - "color":"e9dd00", - "topic_id":2, - "topic_count":1729, - "created_at":"2013-02-01T04:56:34.914Z", - "updated_at":"2015-01-22T18:05:33.426Z", - "user_id":1, - "topics_year":1114, - "topics_month":69, - "topics_week":22, - "slug":"bug", - "description":"A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.", - "text_color":"000000", - "read_restricted":false, - "auto_close_hours":null, - "post_count":11179, - "latest_post_id":94611, - "latest_topic_id":24350, - "position":25, - "parent_category_id":null, - "posts_year":7138, - "posts_month":397, - "posts_week":121, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":1, - "posts_day":6, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"bug", - "auto_close_based_on_last_post":false + id: 94517, + cooked: + "Doubtful this is a bug, probably dependent on the PNG encoding.
\n\nTry using PNGOUT, or converting to 8 bit PNGOUT, to see some of the differences. And PNGOUT is lossless!
", + created_at: "2015-01-23T02:41:30.287Z", + title: "Pasted image upload size error", + url: "/t/pasted-image-upload-size-error/24320/2", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 1, + name: "bug", + color: "e9dd00", + topic_id: 2, + topic_count: 1729, + created_at: "2013-02-01T04:56:34.914Z", + updated_at: "2015-01-22T18:05:33.426Z", + user_id: 1, + topics_year: 1114, + topics_month: 69, + topics_week: 22, + slug: "bug", + description: + "A bug report means something is broken, preventing normal/typical use of Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.", + text_color: "000000", + read_restricted: false, + auto_close_hours: null, + post_count: 11179, + latest_post_id: 94611, + latest_topic_id: 24350, + position: 25, + parent_category_id: null, + posts_year: 7138, + posts_month: 397, + posts_week: 121, + email_in: null, + email_in_allow_strangers: false, + topics_day: 1, + posts_day: 6, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "bug", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94516, - "cooked":"I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.
", - "created_at":"2015-01-23T02:40:11.726Z", - "title":"Monetizing Discourse Talk", - "url":"/t/monetizing-discourse-talk/24316/4", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":6, - "name":"support", - "color":"CEA9A9", - "topic_id":389, - "topic_count":1781, - "created_at":"2013-02-05T22:16:38.672Z", - "updated_at":"2015-01-22T18:05:33.572Z", - "user_id":1, - "topics_year":1541, - "topics_month":167, - "topics_week":49, - "slug":"support", - "description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":12272, - "latest_post_id":94602, - "latest_topic_id":24346, - "position":25, - "parent_category_id":null, - "posts_year":10571, - "posts_month":1254, - "posts_week":413, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":5, - "posts_day":70, - "logo_url":"", - "background_url":"", - "allow_badges":true, - "name_lower":"support", - "auto_close_based_on_last_post":false + id: 94516, + cooked: + "I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.
", + created_at: "2015-01-23T02:40:11.726Z", + title: "Monetizing Discourse Talk", + url: "/t/monetizing-discourse-talk/24316/4", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 6, + name: "support", + color: "CEA9A9", + topic_id: 389, + topic_count: 1781, + created_at: "2013-02-05T22:16:38.672Z", + updated_at: "2015-01-22T18:05:33.572Z", + user_id: 1, + topics_year: 1541, + topics_month: 167, + topics_week: 49, + slug: "support", + description: + "Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 12272, + latest_post_id: 94602, + latest_topic_id: 24346, + position: 25, + parent_category_id: null, + posts_year: 10571, + posts_month: 1254, + posts_week: 413, + email_in: null, + email_in_allow_strangers: false, + topics_day: 5, + posts_day: 70, + logo_url: "", + background_url: "", + allow_badges: true, + name_lower: "support", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94515, - "cooked":"I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.
", - "created_at":"2015-01-23T02:38:29.185Z", - "title":"Introducing Discette - a minimal ember-cli front end to Discourse", - "url":"/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/2", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":7, - "name":"dev", - "color":"000", - "topic_id":1026, - "topic_count":574, - "created_at":"2013-02-06T08:43:41.550Z", - "updated_at":"2015-01-22T18:05:32.855Z", - "user_id":32, - "topics_year":298, - "topics_month":29, - "topics_week":2, - "slug":"dev", - "description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":4196, - "latest_post_id":94590, - "latest_topic_id":24349, - "position":25, - "parent_category_id":null, - "posts_year":2095, - "posts_month":172, - "posts_week":16, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":0, - "posts_day":3, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"dev", - "auto_close_based_on_last_post":false + id: 94515, + cooked: + "I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.
", + created_at: "2015-01-23T02:38:29.185Z", + title: + "Introducing Discette - a minimal ember-cli front end to Discourse", + url: + "/t/introducing-discette-a-minimal-ember-cli-front-end-to-discourse/24321/2", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 7, + name: "dev", + color: "000", + topic_id: 1026, + topic_count: 574, + created_at: "2013-02-06T08:43:41.550Z", + updated_at: "2015-01-22T18:05:32.855Z", + user_id: 32, + topics_year: 298, + topics_month: 29, + topics_week: 2, + slug: "dev", + description: + "This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 4196, + latest_post_id: 94590, + latest_topic_id: 24349, + position: 25, + parent_category_id: null, + posts_year: 2095, + posts_month: 172, + posts_week: 16, + email_in: null, + email_in_allow_strangers: false, + topics_day: 0, + posts_day: 3, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "dev", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94514, - "cooked":"I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.
", - "created_at":"2015-01-23T02:37:39.518Z", - "title":"How to do \"Object Oriented Discussion\" through Oneboxes?", - "url":"/t/how-to-do-object-oriented-discussion-through-oneboxes/24328/2", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":5, - "name":"extensibility", - "color":"FE8432", - "topic_id":28, - "topic_count":295, - "created_at":"2013-02-03T08:42:06.329Z", - "updated_at":"2015-01-22T18:05:32.698Z", - "user_id":1, - "topics_year":187, - "topics_month":17, - "topics_week":7, - "slug":"extensibility", - "description":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility. ", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":2574, - "latest_post_id":94582, - "latest_topic_id":24328, - "position":25, - "parent_category_id":null, - "posts_year":1485, - "posts_month":196, - "posts_week":52, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":2, - "posts_day":8, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"extensibility", - "auto_close_based_on_last_post":false + id: 94514, + cooked: + "I would worry about getting your expenses down to $5 per month, that seems more likely over time as hosting for Docker compliant sites gets cheaper.
", + created_at: "2015-01-23T02:37:39.518Z", + title: 'How to do "Object Oriented Discussion" through Oneboxes?', + url: "/t/how-to-do-object-oriented-discussion-through-oneboxes/24328/2", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 5, + name: "extensibility", + color: "FE8432", + topic_id: 28, + topic_count: 295, + created_at: "2013-02-03T08:42:06.329Z", + updated_at: "2015-01-22T18:05:32.698Z", + user_id: 1, + topics_year: 187, + topics_month: 17, + topics_week: 7, + slug: "extensibility", + description: + "Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility. ", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 2574, + latest_post_id: 94582, + latest_topic_id: 24328, + position: 25, + parent_category_id: null, + posts_year: 1485, + posts_month: 196, + posts_week: 52, + email_in: null, + email_in_allow_strangers: false, + topics_day: 2, + posts_day: 8, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "extensibility", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94512, - "cooked":"Hmm, have not seen problems updating on 1gb instance provided swap is there.
\n\nAnything else running on the machine?
\n\nMaybe reboot, then upgrade Docker from command line, then upgrade Discourse from command line.
", - "created_at":"2015-01-23T02:32:31.383Z", - "title":"Update Failed and Now Showing Currently Upgrading", - "url":"/t/update-failed-and-now-showing-currently-upgrading/24332/2", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":6, - "name":"support", - "color":"CEA9A9", - "topic_id":389, - "topic_count":1781, - "created_at":"2013-02-05T22:16:38.672Z", - "updated_at":"2015-01-22T18:05:33.572Z", - "user_id":1, - "topics_year":1541, - "topics_month":167, - "topics_week":49, - "slug":"support", - "description":"Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":12272, - "latest_post_id":94602, - "latest_topic_id":24346, - "position":25, - "parent_category_id":null, - "posts_year":10571, - "posts_month":1254, - "posts_week":413, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":5, - "posts_day":70, - "logo_url":"", - "background_url":"", - "allow_badges":true, - "name_lower":"support", - "auto_close_based_on_last_post":false + id: 94512, + cooked: + "Hmm, have not seen problems updating on 1gb instance provided swap is there.
\n\nAnything else running on the machine?
\n\nMaybe reboot, then upgrade Docker from command line, then upgrade Discourse from command line.
", + created_at: "2015-01-23T02:32:31.383Z", + title: "Update Failed and Now Showing Currently Upgrading", + url: "/t/update-failed-and-now-showing-currently-upgrading/24332/2", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 6, + name: "support", + color: "CEA9A9", + topic_id: 389, + topic_count: 1781, + created_at: "2013-02-05T22:16:38.672Z", + updated_at: "2015-01-22T18:05:33.572Z", + user_id: 1, + topics_year: 1541, + topics_month: 167, + topics_week: 49, + slug: "support", + description: + "Support on configuring and using Discourse after it is up and running. For installation questions, use the install category.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 12272, + latest_post_id: 94602, + latest_topic_id: 24346, + position: 25, + parent_category_id: null, + posts_year: 10571, + posts_month: 1254, + posts_week: 413, + email_in: null, + email_in_allow_strangers: false, + topics_day: 5, + posts_day: 70, + logo_url: "", + background_url: "", + allow_badges: true, + name_lower: "support", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } }, { - "id":94511, - "cooked":"Hmm, not sure about that, good odds they will be fixed in iOS 8.1 which is due soon.
", - "created_at":"2015-01-23T02:27:16.786Z", - "title":"Dealing with iOS 8 Mobile Safari bugs?", - "url":"/t/dealing-with-ios-8-mobile-safari-bugs/24101/5", - "user_title":"co-founder", - "user_long_name":"Jeff Atwood", - "category":{ - "id":2, - "name":"feature", - "color":"0E76BD", - "topic_id":11, - "topic_count":1592, - "created_at":"2013-02-02T21:42:52.552Z", - "updated_at":"2015-01-22T18:05:32.647Z", - "user_id":1, - "topics_year":919, - "topics_month":60, - "topics_week":20, - "slug":"feature", - "description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.", - "text_color":"FFFFFF", - "read_restricted":false, - "auto_close_hours":null, - "post_count":14360, - "latest_post_id":94600, - "latest_topic_id":24344, - "position":25, - "parent_category_id":null, - "posts_year":8617, - "posts_month":690, - "posts_week":190, - "email_in":null, - "email_in_allow_strangers":false, - "topics_day":2, - "posts_day":8, - "logo_url":null, - "background_url":null, - "allow_badges":true, - "name_lower":"feature", - "auto_close_based_on_last_post":false + id: 94511, + cooked: + "Hmm, not sure about that, good odds they will be fixed in iOS 8.1 which is due soon.
", + created_at: "2015-01-23T02:27:16.786Z", + title: "Dealing with iOS 8 Mobile Safari bugs?", + url: "/t/dealing-with-ios-8-mobile-safari-bugs/24101/5", + user_title: "co-founder", + user_long_name: "Jeff Atwood", + category: { + id: 2, + name: "feature", + color: "0E76BD", + topic_id: 11, + topic_count: 1592, + created_at: "2013-02-02T21:42:52.552Z", + updated_at: "2015-01-22T18:05:32.647Z", + user_id: 1, + topics_year: 919, + topics_month: 60, + topics_week: 20, + slug: "feature", + description: + "Discussion about features or potential features of Discourse: how they work, why they work, etc.", + text_color: "FFFFFF", + read_restricted: false, + auto_close_hours: null, + post_count: 14360, + latest_post_id: 94600, + latest_topic_id: 24344, + position: 25, + parent_category_id: null, + posts_year: 8617, + posts_month: 690, + posts_week: 190, + email_in: null, + email_in_allow_strangers: false, + topics_day: 2, + posts_day: 8, + logo_url: null, + background_url: null, + allow_badges: true, + name_lower: "feature", + auto_close_based_on_last_post: false }, - "user":{ - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" + user: { + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png" } } ] diff --git a/test/javascripts/fixtures/groups-fixtures.js.es6 b/test/javascripts/fixtures/groups-fixtures.js.es6 index 79f47e64cb1..136f8bcb392 100644 --- a/test/javascripts/fixtures/groups-fixtures.js.es6 +++ b/test/javascripts/fixtures/groups-fixtures.js.es6 @@ -1,3 +1,54 @@ export default { - "/groups.json": {"groups":[{"id":41,"automatic":false,"name":"discourse","user_count":0,"alias_level":0,"visible":true,"automatic_membership_email_domains":"","automatic_membership_retroactive":false,"primary_group":false,"title":null,"grant_trust_level":null,"has_messages":false,"flair_url":null,"flair_bg_color":null,"flair_color":null,"bio_raw":"","bio_cooked":null,"public_admission":true,"allow_membership_requests":false,"full_name":"Awesome Team"},{"id":42,"automatic":false,"name":"Macdonald","user_count":0,"alias_level":99,"visible":true,"automatic_membership_email_domains":"","automatic_membership_retroactive":false,"primary_group":false,"title":null,"grant_trust_level":null,"has_messages":false,"flair_url":null,"flair_bg_color":null,"flair_color":null,"bio_raw":null,"bio_cooked":null,"public_admission":false,"allow_membership_requests":true,"membership_request_template":"Please add me","full_name":null}],"extras":{"group_user_ids":[]},"total_rows_groups":2,"load_more_groups":"/groups?page=1"} -} + "/groups.json": { + groups: [ + { + id: 41, + automatic: false, + name: "discourse", + user_count: 0, + alias_level: 0, + visible: true, + automatic_membership_email_domains: "", + automatic_membership_retroactive: false, + primary_group: false, + title: null, + grant_trust_level: null, + has_messages: false, + flair_url: null, + flair_bg_color: null, + flair_color: null, + bio_raw: "", + bio_cooked: null, + public_admission: true, + allow_membership_requests: false, + full_name: "Awesome Team" + }, + { + id: 42, + automatic: false, + name: "Macdonald", + user_count: 0, + alias_level: 99, + visible: true, + automatic_membership_email_domains: "", + automatic_membership_retroactive: false, + primary_group: false, + title: null, + grant_trust_level: null, + has_messages: false, + flair_url: null, + flair_bg_color: null, + flair_color: null, + bio_raw: null, + bio_cooked: null, + public_admission: false, + allow_membership_requests: true, + membership_request_template: "Please add me", + full_name: null + } + ], + extras: { group_user_ids: [] }, + total_rows_groups: 2, + load_more_groups: "/groups?page=1" + } +}; diff --git a/test/javascripts/fixtures/new-contributors.js.es6 b/test/javascripts/fixtures/new-contributors.js.es6 index fc3d6f86c9e..5b89bc059b4 100644 --- a/test/javascripts/fixtures/new-contributors.js.es6 +++ b/test/javascripts/fixtures/new-contributors.js.es6 @@ -1,49 +1,60 @@ export default { "/admin/reports/new_contributors": { - "report": { - "type": "new_contributors", - "title": "New Contributors", - "xaxis": "", - "yaxis": "", - "data": [{ - "x": "2018-04-11", - "y": 10 - }, { - "x": "2018-04-12", - "y": 10 - }, { - "x": "2018-04-13", - "y": 60 - }, { - "x": "2018-04-14", - "y": 60 - }, { - "x": "2018-04-15", - "y": 10 - }, { - "x": "2018-04-16", - "y": 10 - }, { - "x": "2018-04-17", - "y": 10 - }, { - "x": "2018-04-19", - "y": 10 - }, { - "x": "2018-04-18", - "y": 10 - }, { - "x": "2018-04-20", - "y": 1 - }], - "total": 121, - "start_date": "2018-03-26T00:00:00.000Z", - "end_date": "2018-04-25T23:59:59.999Z", - "category_id": null, - "group_id": null, - "prev30Days": null, - "labels": null, - "report_key": "" + report: { + type: "new_contributors", + title: "New Contributors", + xaxis: "", + yaxis: "", + data: [ + { + x: "2018-04-11", + y: 10 + }, + { + x: "2018-04-12", + y: 10 + }, + { + x: "2018-04-13", + y: 60 + }, + { + x: "2018-04-14", + y: 60 + }, + { + x: "2018-04-15", + y: 10 + }, + { + x: "2018-04-16", + y: 10 + }, + { + x: "2018-04-17", + y: 10 + }, + { + x: "2018-04-19", + y: 10 + }, + { + x: "2018-04-18", + y: 10 + }, + { + x: "2018-04-20", + y: 1 + } + ], + total: 121, + start_date: "2018-03-26T00:00:00.000Z", + end_date: "2018-04-25T23:59:59.999Z", + category_id: null, + group_id: null, + prev30Days: null, + labels: null, + report_key: "" } } }; diff --git a/test/javascripts/fixtures/notification_fixtures.js.es6 b/test/javascripts/fixtures/notification_fixtures.js.es6 index a1b092c503c..d9669d9d9b2 100644 --- a/test/javascripts/fixtures/notification_fixtures.js.es6 +++ b/test/javascripts/fixtures/notification_fixtures.js.es6 @@ -1,2 +1,16 @@ /*jshint maxlen:10000000 */ -export default {"/notifications": {notifications: [ { id: 123, notification_type: 2, read: false, post_number: 2, topic_id: 1234, slug: "a-slug", data: { topic_title: "some title", display_username: "velesin" } } ] }}; +export default { + "/notifications": { + notifications: [ + { + id: 123, + notification_type: 2, + read: false, + post_number: 2, + topic_id: 1234, + slug: "a-slug", + data: { topic_title: "some title", display_username: "velesin" } + } + ] + } +}; diff --git a/test/javascripts/fixtures/post.js.es6 b/test/javascripts/fixtures/post.js.es6 index 345c20a1bec..28288e47394 100644 --- a/test/javascripts/fixtures/post.js.es6 +++ b/test/javascripts/fixtures/post.js.es6 @@ -1,6 +1,157 @@ export default { - "/posts/398": {"id":398,"name":"Uwe Keim","username":"uwe_keim","avatar_template":"/user_avatar/meta.discourse.org/uwe_keim/{size}/5697.png","uploaded_avatar_id":5697,"created_at":"2013-02-05T21:29:00.280Z","cooked":"Any plans to support localization of UI elements, so that I (for example) could set up a completely German speaking forum?
","post_number":1,"post_type":1,"updated_at":"2013-02-05T21:29:00.280Z","like_count":0,"reply_count":1,"reply_to_post_number":null,"quote_count":0,"avg_time":25,"incoming_link_count":314,"reads":475,"score":1702.25,"yours":false,"topic_id":280,"topic_slug":"internationalization-localization","display_username":"Uwe Keim","primary_group_name":null,"version":1,"can_edit":true,"can_delete":false,"can_recover":true,"user_title":null,"raw":"Any plans to support localization of UI elements, so that I (for example) could set up a completely German speaking forum?","actions_summary":[{"id":2,"count":0,"hidden":false,"can_act":true,"can_defer_flags":false},{"id":3,"count":0,"hidden":false,"can_act":true,"can_defer_flags":false},{"id":4,"count":0,"hidden":false,"can_act":true,"can_defer_flags":false},{"id":5,"count":0,"hidden":true,"can_act":true,"can_defer_flags":false},{"id":6,"count":0,"hidden":false,"can_act":true,"can_defer_flags":false},{"id":7,"count":0,"hidden":false,"can_act":true,"can_defer_flags":false},{"id":8,"count":0,"hidden":false,"can_act":true,"can_defer_flags":false}],"moderator":false,"admin":false,"staff":false,"user_id":255,"hidden":false,"hidden_reason_id":null,"trust_level":2,"deleted_at":null,"user_deleted":false,"edit_reason":null,"can_view_edit_history":true,"wiki":false}, - "/posts/18": {"id":18,"username":"eviltrout","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","name":"Evil Trout","uploaded_avatar_id":9,"created_at":"2015-08-13T14:49:11.840Z","cooked":"This is the first post.
","post_number":1,"post_type":1,"updated_at":"2015-08-13T14:49:11.840Z","reply_count":0,"reply_to_post_number":null,"quote_count":0,"avg_time":null,"incoming_link_count":0,"reads":1,"score":0,"yours":true,"topic_id":9,"topic_slug":"this-is-a-test-topic","display_username":"","primary_group_name":null,"version":1,"can_edit":true,"can_delete":false,"can_recover":true,"user_title":null,"raw":"This is the first post.","actions_summary":[{"id":3,"can_act":true},{"id":4,"can_act":true},{"id":5,"hidden":true,"can_act":true},{"id":7,"can_act":true},{"id":8,"can_act":true}],"moderator":false,"admin":true,"staff":true,"user_id":1,"hidden":false,"hidden_reason_id":null,"trust_level":4,"deleted_at":null,"user_deleted":false,"edit_reason":null,"can_view_edit_history":true,"wiki":false}, - "/posts/19": {"id":19,"username":"eviltrout","avatar_template":"//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon","name":"Evil Trout","uploaded_avatar_id":9,"created_at":"2015-08-13T14:49:18.231Z","cooked":"This is the second post.
","post_number":2,"post_type":1,"updated_at":"2015-08-13T14:49:18.231Z","reply_count":0,"reply_to_post_number":null,"quote_count":0,"avg_time":null,"incoming_link_count":0,"reads":1,"score":0,"yours":true,"topic_id":9,"topic_slug":"this-is-a-test-topic","display_username":"","primary_group_name":null,"version":1,"can_edit":true,"can_delete":true,"can_recover":true,"read":true,"user_title":null,"raw":"This is the second post.","actions_summary":[{"id":3,"can_act":true},{"id":4,"can_act":true},{"id":5,"hidden":true,"can_act":true},{"id":7,"can_act":true},{"id":8,"can_act":true}],"moderator":false,"admin":true,"staff":true,"user_id":1,"hidden":false,"hidden_reason_id":null,"trust_level":4,"deleted_at":null,"user_deleted":false,"edit_reason":null,"can_view_edit_history":true,"wiki":false} + "/posts/398": { + id: 398, + name: "Uwe Keim", + username: "uwe_keim", + avatar_template: "/user_avatar/meta.discourse.org/uwe_keim/{size}/5697.png", + uploaded_avatar_id: 5697, + created_at: "2013-02-05T21:29:00.280Z", + cooked: + "Any plans to support localization of UI elements, so that I (for example) could set up a completely German speaking forum?
", + post_number: 1, + post_type: 1, + updated_at: "2013-02-05T21:29:00.280Z", + like_count: 0, + reply_count: 1, + reply_to_post_number: null, + quote_count: 0, + avg_time: 25, + incoming_link_count: 314, + reads: 475, + score: 1702.25, + yours: false, + topic_id: 280, + topic_slug: "internationalization-localization", + display_username: "Uwe Keim", + primary_group_name: null, + version: 1, + can_edit: true, + can_delete: false, + can_recover: true, + user_title: null, + raw: + "Any plans to support localization of UI elements, so that I (for example) could set up a completely German speaking forum?", + actions_summary: [ + { id: 2, count: 0, hidden: false, can_act: true, can_defer_flags: false }, + { id: 3, count: 0, hidden: false, can_act: true, can_defer_flags: false }, + { id: 4, count: 0, hidden: false, can_act: true, can_defer_flags: false }, + { id: 5, count: 0, hidden: true, can_act: true, can_defer_flags: false }, + { id: 6, count: 0, hidden: false, can_act: true, can_defer_flags: false }, + { id: 7, count: 0, hidden: false, can_act: true, can_defer_flags: false }, + { id: 8, count: 0, hidden: false, can_act: true, can_defer_flags: false } + ], + moderator: false, + admin: false, + staff: false, + user_id: 255, + hidden: false, + hidden_reason_id: null, + trust_level: 2, + deleted_at: null, + user_deleted: false, + edit_reason: null, + can_view_edit_history: true, + wiki: false + }, + "/posts/18": { + id: 18, + username: "eviltrout", + avatar_template: + "//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon", + name: "Evil Trout", + uploaded_avatar_id: 9, + created_at: "2015-08-13T14:49:11.840Z", + cooked: "This is the first post.
", + post_number: 1, + post_type: 1, + updated_at: "2015-08-13T14:49:11.840Z", + reply_count: 0, + reply_to_post_number: null, + quote_count: 0, + avg_time: null, + incoming_link_count: 0, + reads: 1, + score: 0, + yours: true, + topic_id: 9, + topic_slug: "this-is-a-test-topic", + display_username: "", + primary_group_name: null, + version: 1, + can_edit: true, + can_delete: false, + can_recover: true, + user_title: null, + raw: "This is the first post.", + actions_summary: [ + { id: 3, can_act: true }, + { id: 4, can_act: true }, + { id: 5, hidden: true, can_act: true }, + { id: 7, can_act: true }, + { id: 8, can_act: true } + ], + moderator: false, + admin: true, + staff: true, + user_id: 1, + hidden: false, + hidden_reason_id: null, + trust_level: 4, + deleted_at: null, + user_deleted: false, + edit_reason: null, + can_view_edit_history: true, + wiki: false + }, + "/posts/19": { + id: 19, + username: "eviltrout", + avatar_template: + "//www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon", + name: "Evil Trout", + uploaded_avatar_id: 9, + created_at: "2015-08-13T14:49:18.231Z", + cooked: "This is the second post.
", + post_number: 2, + post_type: 1, + updated_at: "2015-08-13T14:49:18.231Z", + reply_count: 0, + reply_to_post_number: null, + quote_count: 0, + avg_time: null, + incoming_link_count: 0, + reads: 1, + score: 0, + yours: true, + topic_id: 9, + topic_slug: "this-is-a-test-topic", + display_username: "", + primary_group_name: null, + version: 1, + can_edit: true, + can_delete: true, + can_recover: true, + read: true, + user_title: null, + raw: "This is the second post.", + actions_summary: [ + { id: 3, can_act: true }, + { id: 4, can_act: true }, + { id: 5, hidden: true, can_act: true }, + { id: 7, can_act: true }, + { id: 8, can_act: true } + ], + moderator: false, + admin: true, + staff: true, + user_id: 1, + hidden: false, + hidden_reason_id: null, + trust_level: 4, + deleted_at: null, + user_deleted: false, + edit_reason: null, + can_view_edit_history: true, + wiki: false + } }; - diff --git a/test/javascripts/fixtures/posts.js.es6 b/test/javascripts/fixtures/posts.js.es6 index dea89045210..caa70dc3370 100644 --- a/test/javascripts/fixtures/posts.js.es6 +++ b/test/javascripts/fixtures/posts.js.es6 @@ -1,19 +1,19 @@ export default { "/admin/reports/posts": { - "report": { - "type": "topics", - "title": "Topics", - "xaxis": "Day", - "yaxis": "Number of new posts", - "data": null, - "total": null, - "start_date": "2018-03-26T00:00:00.000Z", - "end_date": "2018-04-25T23:59:59.999Z", - "category_id": null, - "group_id": null, - "prev30Days": 0, - "labels": null, - "report_key": "" + report: { + type: "topics", + title: "Topics", + xaxis: "Day", + yaxis: "Number of new posts", + data: null, + total: null, + start_date: "2018-03-26T00:00:00.000Z", + end_date: "2018-04-25T23:59:59.999Z", + category_id: null, + group_id: null, + prev30Days: 0, + labels: null, + report_key: "" } } }; diff --git a/test/javascripts/fixtures/search-fixtures.js.es6 b/test/javascripts/fixtures/search-fixtures.js.es6 index a0b8e22bdaa..d49a7085107 100644 --- a/test/javascripts/fixtures/search-fixtures.js.es6 +++ b/test/javascripts/fixtures/search-fixtures.js.es6 @@ -1,770 +1,818 @@ export default { "/search.json": { - "users":[ + users: [ { - "id":19, - "username":"eviltrout", - "uploaded_avatar_id":5275, - "avatar_template":"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_1.png" + id: 19, + username: "eviltrout", + uploaded_avatar_id: 5275, + avatar_template: + "/user_avatar/meta.discourse.org/eviltrout/{size}/5275_1.png" }, { - "id":8617, - "username":"Mittineague", - "uploaded_avatar_id":40997, - "avatar_template":"/user_avatar/meta.discourse.org/mittineague/{size}/40997_1.png" + id: 8617, + username: "Mittineague", + uploaded_avatar_id: 40997, + avatar_template: + "/user_avatar/meta.discourse.org/mittineague/{size}/40997_1.png" }, { - "id":12662, - "username":"singmajesty", - "uploaded_avatar_id":36342, - "avatar_template":"/user_avatar/meta.discourse.org/singmajesty/{size}/36342_1.png" + id: 12662, + username: "singmajesty", + uploaded_avatar_id: 36342, + avatar_template: + "/user_avatar/meta.discourse.org/singmajesty/{size}/36342_1.png" }, { - "id":6626, - "username":"riking", - "uploaded_avatar_id":40212, - "avatar_template":"/user_avatar/meta.discourse.org/riking/{size}/40212_1.png" + id: 6626, + username: "riking", + uploaded_avatar_id: 40212, + avatar_template: + "/user_avatar/meta.discourse.org/riking/{size}/40212_1.png" }, { - "id":8300, - "username":"cpradio", - "uploaded_avatar_id":4970, - "avatar_template":"/user_avatar/meta.discourse.org/cpradio/{size}/4970_1.png" + id: 8300, + username: "cpradio", + uploaded_avatar_id: 4970, + avatar_template: + "/user_avatar/meta.discourse.org/cpradio/{size}/4970_1.png" }, { - "id":2602, - "username":"georgekaplan59", - "uploaded_avatar_id":31197, - "avatar_template":"/user_avatar/meta.discourse.org/georgekaplan59/{size}/31197_1.png" + id: 2602, + username: "georgekaplan59", + uploaded_avatar_id: 31197, + avatar_template: + "/user_avatar/meta.discourse.org/georgekaplan59/{size}/31197_1.png" }, { - "id":754, - "username":"danneu", - "uploaded_avatar_id":6540, - "avatar_template":"/user_avatar/meta.discourse.org/danneu/{size}/6540_1.png" + id: 754, + username: "danneu", + uploaded_avatar_id: 6540, + avatar_template: + "/user_avatar/meta.discourse.org/danneu/{size}/6540_1.png" }, { - "id":1995, - "username":"zogstrip", - "uploaded_avatar_id":8630, - "avatar_template":"/user_avatar/meta.discourse.org/zogstrip/{size}/8630_1.png" + id: 1995, + username: "zogstrip", + uploaded_avatar_id: 8630, + avatar_template: + "/user_avatar/meta.discourse.org/zogstrip/{size}/8630_1.png" }, { - "id":1, - "username":"sam", - "uploaded_avatar_id":5243, - "avatar_template":"/user_avatar/meta.discourse.org/sam/{size}/5243_1.png" + id: 1, + username: "sam", + uploaded_avatar_id: 5243, + avatar_template: "/user_avatar/meta.discourse.org/sam/{size}/5243_1.png" }, { - "id":8810, - "username":"fantasticfears", - "uploaded_avatar_id":36351, - "avatar_template":"/user_avatar/meta.discourse.org/fantasticfears/{size}/36351_1.png" + id: 8810, + username: "fantasticfears", + uploaded_avatar_id: 36351, + avatar_template: + "/user_avatar/meta.discourse.org/fantasticfears/{size}/36351_1.png" }, { - "id":14446, - "username":"ladydanger", - "uploaded_avatar_id":null, - "avatar_template":"/letter_avatar/ladydanger/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" + id: 14446, + username: "ladydanger", + uploaded_avatar_id: null, + avatar_template: + "/letter_avatar/ladydanger/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" }, { - "id":14474, - "username":"dnatoli_redbubble", - "uploaded_avatar_id":null, - "avatar_template":"/letter_avatar/dnatoli_redbubble/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" + id: 14474, + username: "dnatoli_redbubble", + uploaded_avatar_id: null, + avatar_template: + "/letter_avatar/dnatoli_redbubble/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" }, { - "id":14514, - "username":"adelsmee", - "uploaded_avatar_id":40445, - "avatar_template":"/user_avatar/meta.discourse.org/adelsmee/{size}/40445_1.png" + id: 14514, + username: "adelsmee", + uploaded_avatar_id: 40445, + avatar_template: + "/user_avatar/meta.discourse.org/adelsmee/{size}/40445_1.png" }, { - "id":32, - "username":"codinghorror", - "uploaded_avatar_id":5297, - "avatar_template":"/user_avatar/meta.discourse.org/codinghorror/{size}/5297_1.png" + id: 32, + username: "codinghorror", + uploaded_avatar_id: 5297, + avatar_template: + "/user_avatar/meta.discourse.org/codinghorror/{size}/5297_1.png" }, { - "id":14448, - "username":"snjqi188", - "uploaded_avatar_id":null, - "avatar_template":"/letter_avatar/snjqi188/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" + id: 14448, + username: "snjqi188", + uploaded_avatar_id: null, + avatar_template: + "/letter_avatar/snjqi188/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" }, { - "id":14657, - "username":"Alex_Flom", - "uploaded_avatar_id":41037, - "avatar_template":"/user_avatar/meta.discourse.org/alex_flom/{size}/41037_1.png" + id: 14657, + username: "Alex_Flom", + uploaded_avatar_id: 41037, + avatar_template: + "/user_avatar/meta.discourse.org/alex_flom/{size}/41037_1.png" }, { - "id":14353, - "username":"Simon_Cossar", - "uploaded_avatar_id":40130, - "avatar_template":"/user_avatar/meta.discourse.org/simon_cossar/{size}/40130_1.png" + id: 14353, + username: "Simon_Cossar", + uploaded_avatar_id: 40130, + avatar_template: + "/user_avatar/meta.discourse.org/simon_cossar/{size}/40130_1.png" }, { - "id":14184, - "username":"takaminacchan", - "uploaded_avatar_id":39685, - "avatar_template":"/user_avatar/meta.discourse.org/takaminacchan/{size}/39685_1.png" + id: 14184, + username: "takaminacchan", + uploaded_avatar_id: 39685, + avatar_template: + "/user_avatar/meta.discourse.org/takaminacchan/{size}/39685_1.png" }, { - "id":9931, - "username":"Frank", - "uploaded_avatar_id":null, - "avatar_template":"/letter_avatar/frank/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" + id: 9931, + username: "Frank", + uploaded_avatar_id: null, + avatar_template: + "/letter_avatar/frank/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" }, { - "id":8364, - "username":"codetricity", - "uploaded_avatar_id":3773, - "avatar_template":"/user_avatar/meta.discourse.org/codetricity/{size}/3773_1.png" + id: 8364, + username: "codetricity", + uploaded_avatar_id: 3773, + avatar_template: + "/user_avatar/meta.discourse.org/codetricity/{size}/3773_1.png" }, { - "id":4949, - "username":"brodock", - "uploaded_avatar_id":13541, - "avatar_template":"/user_avatar/meta.discourse.org/brodock/{size}/13541_1.png" + id: 4949, + username: "brodock", + uploaded_avatar_id: 13541, + avatar_template: + "/user_avatar/meta.discourse.org/brodock/{size}/13541_1.png" }, { - "id":14, - "username":"clay", - "uploaded_avatar_id":5265, - "avatar_template":"/user_avatar/meta.discourse.org/clay/{size}/5265_1.png" + id: 14, + username: "clay", + uploaded_avatar_id: 5265, + avatar_template: + "/user_avatar/meta.discourse.org/clay/{size}/5265_1.png" }, { - "id":8385, - "username":"zchrykng", - "uploaded_avatar_id":18517, - "avatar_template":"/user_avatar/meta.discourse.org/zchrykng/{size}/18517_1.png" + id: 8385, + username: "zchrykng", + uploaded_avatar_id: 18517, + avatar_template: + "/user_avatar/meta.discourse.org/zchrykng/{size}/18517_1.png" }, { - "id":3520, - "username":"arlyxiao", - "uploaded_avatar_id":11206, - "avatar_template":"/user_avatar/meta.discourse.org/arlyxiao/{size}/11206_1.png" + id: 3520, + username: "arlyxiao", + uploaded_avatar_id: 11206, + avatar_template: + "/user_avatar/meta.discourse.org/arlyxiao/{size}/11206_1.png" }, { - "id":3493, - "username":"richp10", - "uploaded_avatar_id":11160, - "avatar_template":"/user_avatar/meta.discourse.org/richp10/{size}/11160_1.png" + id: 3493, + username: "richp10", + uploaded_avatar_id: 11160, + avatar_template: + "/user_avatar/meta.discourse.org/richp10/{size}/11160_1.png" }, { - "id":2395, - "username":"lookingsideways", - "uploaded_avatar_id":9290, - "avatar_template":"/user_avatar/meta.discourse.org/lookingsideways/{size}/9290_1.png" + id: 2395, + username: "lookingsideways", + uploaded_avatar_id: 9290, + avatar_template: + "/user_avatar/meta.discourse.org/lookingsideways/{size}/9290_1.png" }, { - "id":2477, - "username":"billybonks", - "uploaded_avatar_id":9430, - "avatar_template":"/user_avatar/meta.discourse.org/billybonks/{size}/9430_1.png" + id: 2477, + username: "billybonks", + uploaded_avatar_id: 9430, + avatar_template: + "/user_avatar/meta.discourse.org/billybonks/{size}/9430_1.png" }, { - "id":7301, - "username":"jasonwhat", - "uploaded_avatar_id":null, - "avatar_template":"/letter_avatar/jasonwhat/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" + id: 7301, + username: "jasonwhat", + uploaded_avatar_id: null, + avatar_template: + "/letter_avatar/jasonwhat/{size}/5_fcf819f9b3791cb8c87edf29c8984f83.png" }, { - "id":1819, - "username":"stephan", - "uploaded_avatar_id":8327, - "avatar_template":"/user_avatar/meta.discourse.org/stephan/{size}/8327_1.png" + id: 1819, + username: "stephan", + uploaded_avatar_id: 8327, + avatar_template: + "/user_avatar/meta.discourse.org/stephan/{size}/8327_1.png" }, { - "id":2, - "username":"neil", - "uploaded_avatar_id":5245, - "avatar_template":"/user_avatar/meta.discourse.org/neil/{size}/5245_1.png" + id: 2, + username: "neil", + uploaded_avatar_id: 5245, + avatar_template: + "/user_avatar/meta.discourse.org/neil/{size}/5245_1.png" }, { - "id":2471, - "username":"robconery", - "uploaded_avatar_id":9418, - "avatar_template":"/user_avatar/meta.discourse.org/robconery/{size}/9418_1.png" + id: 2471, + username: "robconery", + uploaded_avatar_id: 9418, + avatar_template: + "/user_avatar/meta.discourse.org/robconery/{size}/9418_1.png" } ], - "topic_list":{ - "can_create_topic":false, - "draft":null, - "draft_key":"new_topic", - "draft_sequence":null, - "per_page":30, - "topics":[ + topic_list: { + can_create_topic: false, + draft: null, + draft_key: "new_topic", + draft_sequence: null, + per_page: 30, + topics: [ { - "id":9318, - "title":"Discourse has a new Markdown Parser!", - "fancy_title":"Discourse has a new Markdown Parser!", - "slug":"discourse-has-a-new-markdown-parser", - "posts_count":1, - "reply_count":0, - "highest_post_number":1, - "image_url":null, - "created_at":"2013-08-24T18:08:06.063Z", - "last_posted_at":"2013-08-24T18:08:06.259Z", - "bumped":true, - "bumped_at":"2015-03-09T04:54:43.977Z", - "unseen":false, - "linked_post_number":1, - "pinned":false, - "unpinned":null, - "excerpt":"...0 lines of Javascript code! An inline example Let's say you want to replace all occurances of \"evil trout\" with a link that says \"EVIL TROUT IS AWESOME\": Discourse.Dialect.on(\"register\", function(event) {...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":2645, - "like_count":21, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"eviltrout", - "category_id":7, - "pinned_globally":false, - "posters":[ + id: 9318, + title: "Discourse has a new Markdown Parser!", + fancy_title: "Discourse has a new Markdown Parser!", + slug: "discourse-has-a-new-markdown-parser", + posts_count: 1, + reply_count: 0, + highest_post_number: 1, + image_url: null, + created_at: "2013-08-24T18:08:06.063Z", + last_posted_at: "2013-08-24T18:08:06.259Z", + bumped: true, + bumped_at: "2015-03-09T04:54:43.977Z", + unseen: false, + linked_post_number: 1, + pinned: false, + unpinned: null, + excerpt: + '...0 lines of Javascript code! An inline example Let\'s say you want to replace all occurances of "evil trout" with a link that says "EVIL TROUT IS AWESOME": Discourse.Dialect.on("register", function(event) {...', + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 2645, + like_count: 21, + has_summary: false, + archetype: "regular", + last_poster_username: "eviltrout", + category_id: 7, + pinned_globally: false, + posters: [ { - "extras":"latest single", - "description":"Original Poster, Most Recent Poster", - "user_id":19 + extras: "latest single", + description: "Original Poster, Most Recent Poster", + user_id: 19 } ] }, { - "id":21792, - "title":"Adding custom emoji/emoticons via a plugin", - "fancy_title":"Adding custom emoji/emoticons via a plugin", - "slug":"adding-custom-emoji-emoticons-via-a-plugin", - "posts_count":34, - "reply_count":24, - "highest_post_number":35, - "image_url":null, - "created_at":"2014-11-03T21:48:48.283Z", - "last_posted_at":"2014-12-23T12:45:11.245Z", - "bumped":true, - "bumped_at":"2014-12-23T12:45:11.245Z", - "unseen":false, - "linked_post_number":1, - "pinned":false, - "unpinned":null, - "excerpt":"...plugin that executes the following method to register a new emoji: Discourse.Dialect.registerEmoji('trout', 'http://cdn.eviltrout.com/images/trout-square.jpg'); Here's a sample plugin that adds a :trout: e...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":1260, - "like_count":25, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"cpradio", - "category_id":22, - "pinned_globally":false, - "posters":[ + id: 21792, + title: "Adding custom emoji/emoticons via a plugin", + fancy_title: "Adding custom emoji/emoticons via a plugin", + slug: "adding-custom-emoji-emoticons-via-a-plugin", + posts_count: 34, + reply_count: 24, + highest_post_number: 35, + image_url: null, + created_at: "2014-11-03T21:48:48.283Z", + last_posted_at: "2014-12-23T12:45:11.245Z", + bumped: true, + bumped_at: "2014-12-23T12:45:11.245Z", + unseen: false, + linked_post_number: 1, + pinned: false, + unpinned: null, + excerpt: + "...plugin that executes the following method to register a new emoji: Discourse.Dialect.registerEmoji('trout', 'http://cdn.eviltrout.com/images/trout-square.jpg'); Here's a sample plugin that adds a :trout: e...", + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 1260, + like_count: 25, + has_summary: false, + archetype: "regular", + last_poster_username: "cpradio", + category_id: 22, + pinned_globally: false, + posters: [ { - "extras":null, - "description":"Original Poster", - "user_id":19 + extras: null, + description: "Original Poster", + user_id: 19 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":8617 + extras: null, + description: "Frequent Poster", + user_id: 8617 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":12662 + extras: null, + description: "Frequent Poster", + user_id: 12662 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":6626 + extras: null, + description: "Frequent Poster", + user_id: 6626 }, { - "extras":"latest", - "description":"Most Recent Poster", - "user_id":8300 + extras: "latest", + description: "Most Recent Poster", + user_id: 8300 } ] }, { - "id":3071, - "title":"Would it be possible to make Slug localizable?", - "fancy_title":"Would it be possible to make Slug localizable?", - "slug":"would-it-be-possible-to-make-slug-localizable", - "posts_count":12, - "reply_count":7, - "highest_post_number":12, - "image_url":null, - "created_at":"2013-02-14T11:48:21.474Z", - "last_posted_at":"2014-09-18T14:38:59.064Z", - "bumped":true, - "bumped_at":"2014-09-18T14:38:59.064Z", - "unseen":false, - "linked_post_number":10, - "pinned":false, - "unpinned":null, - "excerpt":"...in `block (2 levels) in < top (required) > ' 3) Slug replaces symbols Failure/Error: Slug.for('evil#trout').should == 'evil-trout' expected: \"evil-trout\" got: \"evil-number-trout\" (using ==) # ./spec/compon...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":766, - "like_count":5, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"fantasticfears", - "category_id":17, - "pinned_globally":false, - "posters":[ + id: 3071, + title: "Would it be possible to make Slug localizable?", + fancy_title: "Would it be possible to make Slug localizable?", + slug: "would-it-be-possible-to-make-slug-localizable", + posts_count: 12, + reply_count: 7, + highest_post_number: 12, + image_url: null, + created_at: "2013-02-14T11:48:21.474Z", + last_posted_at: "2014-09-18T14:38:59.064Z", + bumped: true, + bumped_at: "2014-09-18T14:38:59.064Z", + unseen: false, + linked_post_number: 10, + pinned: false, + unpinned: null, + excerpt: + "...in `block (2 levels) in < top (required) > ' 3) Slug replaces symbols Failure/Error: Slug.for('evil#trout').should == 'evil-trout' expected: \"evil-trout\" got: \"evil-number-trout\" (using ==) # ./spec/compon...", + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 766, + like_count: 5, + has_summary: false, + archetype: "regular", + last_poster_username: "fantasticfears", + category_id: 17, + pinned_globally: false, + posters: [ { - "extras":null, - "description":"Original Poster", - "user_id":2602 + extras: null, + description: "Original Poster", + user_id: 2602 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":754 + extras: null, + description: "Frequent Poster", + user_id: 754 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":1995 + extras: null, + description: "Frequent Poster", + user_id: 1995 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":1 + extras: null, + description: "Frequent Poster", + user_id: 1 }, { - "extras":"latest", - "description":"Most Recent Poster", - "user_id":8810 + extras: "latest", + description: "Most Recent Poster", + user_id: 8810 } ] }, { - "id":26875, - "title":"Rails Girls SoC Banter", - "fancy_title":"Rails Girls SoC Banter", - "slug":"rails-girls-soc-banter", - "posts_count":48, - "reply_count":30, - "highest_post_number":48, - "image_url":null, - "created_at":"2015-03-27T11:26:09.903Z", - "last_posted_at":"2015-07-13T23:11:31.481Z", - "bumped":true, - "bumped_at":"2015-07-13T23:11:31.481Z", - "unseen":false, - "linked_post_number":42, - "pinned":false, - "unpinned":null, - "excerpt":"...e inserted by plugins. ## Usage If you handlebars template has: ```handlebars {{plugin-outlet \"evil-trout\"}} ``` Then any handlebars files you create in the `connectors/evil-trout` directory will automatic...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":1224, - "like_count":81, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"snjqi188", - "category_id":7, - "pinned_globally":false, - "posters":[ + id: 26875, + title: "Rails Girls SoC Banter", + fancy_title: "Rails Girls SoC Banter", + slug: "rails-girls-soc-banter", + posts_count: 48, + reply_count: 30, + highest_post_number: 48, + image_url: null, + created_at: "2015-03-27T11:26:09.903Z", + last_posted_at: "2015-07-13T23:11:31.481Z", + bumped: true, + bumped_at: "2015-07-13T23:11:31.481Z", + unseen: false, + linked_post_number: 42, + pinned: false, + unpinned: null, + excerpt: + '...e inserted by plugins. ## Usage If you handlebars template has: ```handlebars {{plugin-outlet "evil-trout"}} ``` Then any handlebars files you create in the `connectors/evil-trout` directory will automatic...', + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 1224, + like_count: 81, + has_summary: false, + archetype: "regular", + last_poster_username: "snjqi188", + category_id: 7, + pinned_globally: false, + posters: [ { - "extras":null, - "description":"Original Poster", - "user_id":14446 + extras: null, + description: "Original Poster", + user_id: 14446 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":14474 + extras: null, + description: "Frequent Poster", + user_id: 14474 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":14514 + extras: null, + description: "Frequent Poster", + user_id: 14514 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":32 + extras: null, + description: "Frequent Poster", + user_id: 32 }, { - "extras":"latest", - "description":"Most Recent Poster", - "user_id":14448 + extras: "latest", + description: "Most Recent Poster", + user_id: 14448 } ] }, { - "id":31001, - "title":"Beginner's Guide to Creating Discourse Plugins Part 2: Plugin Outlets", - "fancy_title":"Beginner’s Guide to Creating Discourse Plugins Part 2: Plugin Outlets", - "slug":"beginners-guide-to-creating-discourse-plugins-part-2-plugin-outlets", - "posts_count":1, - "reply_count":0, - "highest_post_number":1, - "image_url":null, - "created_at":"2015-07-12T17:48:27.322Z", - "last_posted_at":"2015-07-12T17:48:27.403Z", - "bumped":true, - "bumped_at":"2015-07-13T04:18:14.901Z", - "unseen":false, - "linked_post_number":1, - "pinned":false, - "unpinned":null, - "excerpt":"...nectors/ < outlet name > in it. For example, if your handlebars template has: {{plugin-outlet \"evil-trout\"}} Then any handlebars files you create in the connectors/evil-trout directory will automatically b...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":220, - "like_count":16, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"eviltrout", - "category_id":10, - "pinned_globally":false, - "posters":[ + id: 31001, + title: + "Beginner's Guide to Creating Discourse Plugins Part 2: Plugin Outlets", + fancy_title: + "Beginner’s Guide to Creating Discourse Plugins Part 2: Plugin Outlets", + slug: + "beginners-guide-to-creating-discourse-plugins-part-2-plugin-outlets", + posts_count: 1, + reply_count: 0, + highest_post_number: 1, + image_url: null, + created_at: "2015-07-12T17:48:27.322Z", + last_posted_at: "2015-07-12T17:48:27.403Z", + bumped: true, + bumped_at: "2015-07-13T04:18:14.901Z", + unseen: false, + linked_post_number: 1, + pinned: false, + unpinned: null, + excerpt: + '...nectors/ < outlet name > in it. For example, if your handlebars template has: {{plugin-outlet "evil-trout"}} Then any handlebars files you create in the connectors/evil-trout directory will automatically b...', + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 220, + like_count: 16, + has_summary: false, + archetype: "regular", + last_poster_username: "eviltrout", + category_id: 10, + pinned_globally: false, + posters: [ { - "extras":"latest single", - "description":"Original Poster, Most Recent Poster", - "user_id":19 + extras: "latest single", + description: "Original Poster, Most Recent Poster", + user_id: 19 } ] }, { - "id":29176, - "title":"How can I add some custom html to the bottom of the categories page?", - "fancy_title":"How can I add some custom html to the bottom of the categories page?", - "slug":"how-can-i-add-some-custom-html-to-the-bottom-of-the-categories-page", - "posts_count":12, - "reply_count":10, - "highest_post_number":13, - "image_url":null, - "created_at":"2015-05-23T19:08:35.447Z", - "last_posted_at":"2015-05-25T08:16:25.989Z", - "bumped":true, - "bumped_at":"2015-05-25T08:16:25.989Z", - "unseen":false, - "linked_post_number":12, - "pinned":false, - "unpinned":null, - "excerpt":"...e inserted by plugins. ## Usage If you handlebars template has: ```handlebars {{plugin-outlet \"evil-trout\"}} ``` Then any handlebars files you create in the `connectors/evil-trout` directory will automatic...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":190, - "like_count":8, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"sam", - "category_id":6, - "pinned_globally":false, - "posters":[ + id: 29176, + title: + "How can I add some custom html to the bottom of the categories page?", + fancy_title: + "How can I add some custom html to the bottom of the categories page?", + slug: + "how-can-i-add-some-custom-html-to-the-bottom-of-the-categories-page", + posts_count: 12, + reply_count: 10, + highest_post_number: 13, + image_url: null, + created_at: "2015-05-23T19:08:35.447Z", + last_posted_at: "2015-05-25T08:16:25.989Z", + bumped: true, + bumped_at: "2015-05-25T08:16:25.989Z", + unseen: false, + linked_post_number: 12, + pinned: false, + unpinned: null, + excerpt: + '...e inserted by plugins. ## Usage If you handlebars template has: ```handlebars {{plugin-outlet "evil-trout"}} ``` Then any handlebars files you create in the `connectors/evil-trout` directory will automatic...', + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 190, + like_count: 8, + has_summary: false, + archetype: "regular", + last_poster_username: "sam", + category_id: 6, + pinned_globally: false, + posters: [ { - "extras":null, - "description":"Original Poster", - "user_id":14657 + extras: null, + description: "Original Poster", + user_id: 14657 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":6626 + extras: null, + description: "Frequent Poster", + user_id: 6626 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":8617 + extras: null, + description: "Frequent Poster", + user_id: 8617 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":14353 + extras: null, + description: "Frequent Poster", + user_id: 14353 }, { - "extras":"latest", - "description":"Most Recent Poster", - "user_id":1 + extras: "latest", + description: "Most Recent Poster", + user_id: 1 } ] }, { - "id":26192, - "title":"403 when embedding a DigitalOcean droplet", - "fancy_title":"403 when embedding a DigitalOcean droplet", - "slug":"403-when-embedding-a-digital-ocean-droplet", - "posts_count":7, - "reply_count":3, - "highest_post_number":7, - "image_url":null, - "created_at":"2015-03-10T21:22:19.206Z", - "last_posted_at":"2015-03-11T22:31:04.520Z", - "bumped":true, - "bumped_at":"2015-03-11T22:31:04.520Z", - "unseen":false, - "linked_post_number":4, - "pinned":false, - "unpinned":null, - "excerpt":"Yes I am Robin as well as Evil Trout smile :smile: If you followed those instructions and are getting access errors, you might want to d...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":232, - "like_count":2, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"codinghorror", - "category_id":6, - "pinned_globally":false, - "posters":[ + id: 26192, + title: "403 when embedding a DigitalOcean droplet", + fancy_title: "403 when embedding a DigitalOcean droplet", + slug: "403-when-embedding-a-digital-ocean-droplet", + posts_count: 7, + reply_count: 3, + highest_post_number: 7, + image_url: null, + created_at: "2015-03-10T21:22:19.206Z", + last_posted_at: "2015-03-11T22:31:04.520Z", + bumped: true, + bumped_at: "2015-03-11T22:31:04.520Z", + unseen: false, + linked_post_number: 4, + pinned: false, + unpinned: null, + excerpt: + "Yes I am Robin as well as Evil Trout smile :smile: If you followed those instructions and are getting access errors, you might want to d...", + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 232, + like_count: 2, + has_summary: false, + archetype: "regular", + last_poster_username: "codinghorror", + category_id: 6, + pinned_globally: false, + posters: [ { - "extras":null, - "description":"Original Poster", - "user_id":14184 + extras: null, + description: "Original Poster", + user_id: 14184 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":19 + extras: null, + description: "Frequent Poster", + user_id: 19 }, { - "extras":"latest", - "description":"Most Recent Poster", - "user_id":32 + extras: "latest", + description: "Most Recent Poster", + user_id: 32 } ] }, { - "id":20883, - "title":"S3 competitor integration", - "fancy_title":"S3 competitor integration", - "slug":"s3-competitor-integration", - "posts_count":3, - "reply_count":1, - "highest_post_number":3, - "image_url":"https://discourse-cdn.global.ssl.fastly.net/meta/images/emoji/twitter/smile.png?v=1", - "created_at":"2014-10-07T13:37:19.628Z", - "last_posted_at":"2014-10-07T18:46:22.493Z", - "bumped":true, - "bumped_at":"2014-10-07T18:46:22.493Z", - "unseen":false, - "linked_post_number":3, - "pinned":false, - "unpinned":null, - "excerpt":"I have seem some of your testing 'stuff' (evil trout's actually). And it looks like a HUUUUUUUUGGGE time sink (ice pick to the eyeballs). but...I believ...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":141, - "like_count":2, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"Frank", - "category_id":2, - "pinned_globally":false, - "posters":[ + id: 20883, + title: "S3 competitor integration", + fancy_title: "S3 competitor integration", + slug: "s3-competitor-integration", + posts_count: 3, + reply_count: 1, + highest_post_number: 3, + image_url: + "https://discourse-cdn.global.ssl.fastly.net/meta/images/emoji/twitter/smile.png?v=1", + created_at: "2014-10-07T13:37:19.628Z", + last_posted_at: "2014-10-07T18:46:22.493Z", + bumped: true, + bumped_at: "2014-10-07T18:46:22.493Z", + unseen: false, + linked_post_number: 3, + pinned: false, + unpinned: null, + excerpt: + "I have seem some of your testing 'stuff' (evil trout's actually). And it looks like a HUUUUUUUUGGGE time sink (ice pick to the eyeballs). but...I believ...", + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 141, + like_count: 2, + has_summary: false, + archetype: "regular", + last_poster_username: "Frank", + category_id: 2, + pinned_globally: false, + posters: [ { - "extras":"latest", - "description":"Original Poster, Most Recent Poster", - "user_id":9931 + extras: "latest", + description: "Original Poster, Most Recent Poster", + user_id: 9931 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":1995 + extras: null, + description: "Frequent Poster", + user_id: 1995 } ] }, { - "id":13534, - "title":"Blogging Platforms, Ghost, and Discourse", - "fancy_title":"Blogging Platforms, Ghost, and Discourse", - "slug":"blogging-platforms-ghost-and-discourse", - "posts_count":18, - "reply_count":13, - "highest_post_number":18, - "image_url":null, - "created_at":"2014-03-08T15:46:35.174Z", - "last_posted_at":"2014-03-26T18:25:45.895Z", - "bumped":true, - "bumped_at":"2014-03-26T18:25:45.895Z", - "unseen":false, - "linked_post_number":1, - "pinned":false, - "unpinned":null, - "excerpt":"...urse, do you mean that the blog comments for Ghost will be driven by Discourse, similar to the Evil Trout blog ? What about using Discourse as the blog platform itself, not as the comment engine at the end...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":2182, - "like_count":17, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"codetricity", - "category_id":17, - "pinned_globally":false, - "posters":[ + id: 13534, + title: "Blogging Platforms, Ghost, and Discourse", + fancy_title: "Blogging Platforms, Ghost, and Discourse", + slug: "blogging-platforms-ghost-and-discourse", + posts_count: 18, + reply_count: 13, + highest_post_number: 18, + image_url: null, + created_at: "2014-03-08T15:46:35.174Z", + last_posted_at: "2014-03-26T18:25:45.895Z", + bumped: true, + bumped_at: "2014-03-26T18:25:45.895Z", + unseen: false, + linked_post_number: 1, + pinned: false, + unpinned: null, + excerpt: + "...urse, do you mean that the blog comments for Ghost will be driven by Discourse, similar to the Evil Trout blog ? What about using Discourse as the blog platform itself, not as the comment engine at the end...", + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 2182, + like_count: 17, + has_summary: false, + archetype: "regular", + last_poster_username: "codetricity", + category_id: 17, + pinned_globally: false, + posters: [ { - "extras":"latest", - "description":"Original Poster, Most Recent Poster", - "user_id":8364 + extras: "latest", + description: "Original Poster, Most Recent Poster", + user_id: 8364 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":4949 + extras: null, + description: "Frequent Poster", + user_id: 4949 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":14 + extras: null, + description: "Frequent Poster", + user_id: 14 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":32 + extras: null, + description: "Frequent Poster", + user_id: 32 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":8385 + extras: null, + description: "Frequent Poster", + user_id: 8385 } ] }, { - "id":4859, - "title":"All of the site functions based on ajax?", - "fancy_title":"All of the site functions based on ajax?", - "slug":"all-of-the-site-functions-based-on-ajax", - "posts_count":28, - "reply_count":20, - "highest_post_number":28, - "image_url":null, - "created_at":"2013-03-18T08:59:46.135Z", - "last_posted_at":"2013-10-18T20:22:30.677Z", - "bumped":true, - "bumped_at":"2013-10-18T20:22:30.677Z", - "unseen":false, - "linked_post_number":21, - "pinned":false, - "unpinned":null, - "excerpt":"please see evil trouts blog post http://eviltrout.com/2013/02/27/adding-to-discourse-part-1.html", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":1629, - "like_count":17, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"jasonwhat", - "category_id":17, - "pinned_globally":false, - "posters":[ + id: 4859, + title: "All of the site functions based on ajax?", + fancy_title: "All of the site functions based on ajax?", + slug: "all-of-the-site-functions-based-on-ajax", + posts_count: 28, + reply_count: 20, + highest_post_number: 28, + image_url: null, + created_at: "2013-03-18T08:59:46.135Z", + last_posted_at: "2013-10-18T20:22:30.677Z", + bumped: true, + bumped_at: "2013-10-18T20:22:30.677Z", + unseen: false, + linked_post_number: 21, + pinned: false, + unpinned: null, + excerpt: + "please see evil trouts blog post http://eviltrout.com/2013/02/27/adding-to-discourse-part-1.html", + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 1629, + like_count: 17, + has_summary: false, + archetype: "regular", + last_poster_username: "jasonwhat", + category_id: 17, + pinned_globally: false, + posters: [ { - "extras":null, - "description":"Original Poster", - "user_id":3520 + extras: null, + description: "Original Poster", + user_id: 3520 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":3493 + extras: null, + description: "Frequent Poster", + user_id: 3493 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":2395 + extras: null, + description: "Frequent Poster", + user_id: 2395 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":2477 + extras: null, + description: "Frequent Poster", + user_id: 2477 }, { - "extras":"latest", - "description":"Most Recent Poster", - "user_id":7301 + extras: "latest", + description: "Most Recent Poster", + user_id: 7301 } ] }, { - "id":7220, - "title":"Javascript dependencies", - "fancy_title":"Javascript dependencies", - "slug":"javascript-dependencies", - "posts_count":8, - "reply_count":5, - "highest_post_number":8, - "image_url":null, - "created_at":"2013-06-06T11:11:18.522Z", - "last_posted_at":"2013-06-07T18:43:51.449Z", - "bumped":true, - "bumped_at":"2013-06-07T18:43:51.449Z", - "unseen":false, - "linked_post_number":3, - "pinned":false, - "unpinned":null, - "excerpt":"...ould be in vendor directory of one of the gems Ahh I need to look at Gemfile Ahh I need to use Evil Trouts bundle open handlebars trick. I am completely against this new best practice, its inconsistent wit...", - "visible":true, - "closed":false, - "archived":false, - "bookmarked":null, - "liked":null, - "views":1010, - "like_count":0, - "has_summary":false, - "archetype":"regular", - "last_poster_username":"eviltrout", - "category_id":7, - "pinned_globally":false, - "posters":[ + id: 7220, + title: "Javascript dependencies", + fancy_title: "Javascript dependencies", + slug: "javascript-dependencies", + posts_count: 8, + reply_count: 5, + highest_post_number: 8, + image_url: null, + created_at: "2013-06-06T11:11:18.522Z", + last_posted_at: "2013-06-07T18:43:51.449Z", + bumped: true, + bumped_at: "2013-06-07T18:43:51.449Z", + unseen: false, + linked_post_number: 3, + pinned: false, + unpinned: null, + excerpt: + "...ould be in vendor directory of one of the gems Ahh I need to look at Gemfile Ahh I need to use Evil Trouts bundle open handlebars trick. I am completely against this new best practice, its inconsistent wit...", + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + views: 1010, + like_count: 0, + has_summary: false, + archetype: "regular", + last_poster_username: "eviltrout", + category_id: 7, + pinned_globally: false, + posters: [ { - "extras":null, - "description":"Original Poster", - "user_id":1819 + extras: null, + description: "Original Poster", + user_id: 1819 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":2 + extras: null, + description: "Frequent Poster", + user_id: 2 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":1 + extras: null, + description: "Frequent Poster", + user_id: 1 }, { - "extras":null, - "description":"Frequent Poster", - "user_id":2471 + extras: null, + description: "Frequent Poster", + user_id: 2471 }, { - "extras":"latest", - "description":"Most Recent Poster", - "user_id":19 + extras: "latest", + description: "Most Recent Poster", + user_id: 19 } ] } @@ -772,668 +820,684 @@ export default { } }, "search/query": { - "posts": [ - { - "id": 3833, - "name": "Bill Dudney", - "username": "bdudney", - "avatar_template": "/user_avatar/meta.discourse.org/bdudney/{size}/8343_1.png", - "uploaded_avatar_id": 8343, - "created_at": "2013-02-07T17:46:57.469Z", - "cooked": "I've gotten vagrant up and running with a development environment but it's taking forever to load.<\/p>\n\n
For example http://192.168.10.200:3000/<\/a> takes tens of seconds to load.<\/p>\n\n I'm running the whole stack on a new rMBP with OS X 10.8.2.<\/p>\n\n Any ideas of what I've done wrong? Or is this just a function of being on the bleeding edge?<\/p>\n\n Thanks,<\/p>\n\n -bd<\/p>",
- "post_number": 1,
- "post_type": 1,
- "updated_at": "2013-02-07T17:46:57.469Z",
- "like_count": 0,
- "reply_count": 1,
- "reply_to_post_number": null,
- "quote_count": 0,
- "avg_time": 24,
- "incoming_link_count": 4422,
- "reads": 327,
- "score": 21978.4,
- "yours": false,
- "topic_id": 2179,
- "topic_slug": "development-mode-super-slow",
- "display_username": "Bill Dudney",
- "primary_group_name": null,
- "version": 2,
- "can_edit": false,
- "can_delete": false,
- "can_recover": false,
- "user_title": null,
- "actions_summary": [
- {
- "id": 2,
- "count": 0,
- "hidden": false,
- "can_act": false
- },
- {
- "id": 3,
- "count": 0,
- "hidden": false,
- "can_act": false
- },
- {
- "id": 4,
- "count": 0,
- "hidden": false,
- "can_act": false
- },
- {
- "id": 5,
- "count": 0,
- "hidden": true,
- "can_act": false
- },
- {
- "id": 6,
- "count": 0,
- "hidden": false,
- "can_act": false
- },
- {
- "id": 7,
- "count": 0,
- "hidden": false,
- "can_act": false
- },
- {
- "id": 8,
- "count": 0,
- "hidden": false,
- "can_act": false
- }
- ],
- "moderator": false,
- "admin": false,
- "staff": false,
- "user_id": 1828,
- "hidden": false,
- "hidden_reason_id": null,
- "trust_level": 1,
- "deleted_at": null,
- "user_deleted": false,
- "edit_reason": null,
- "can_view_edit_history": true,
- "wiki": false,
- "blurb": "I've gotten vagrant up and running with a development environment but it's taking forever to load. For example http://192.168.10.200:3000/ takes..."
- },
- {
- "id": 48887,
- "name": "Arpit Jalan",
- "username": "techAPJ",
- "avatar_template": "/user_avatar/meta.discourse.org/techapj/{size}/3281_1.png",
- "uploaded_avatar_id": 3281,
- "created_at": "2014-04-12T22:22:07.930Z",
- "cooked": " So you want to set up Discourse on Ubuntu to hack on and develop with?<\/p>\n\n We'll assume that you don't have Ruby/Rails/Postgre/Redis installed on your Ubuntu system. Let's begin!<\/p>\n\n Although this guide assumes that you are using Ubuntu, but the set-up instructions will work fine for any Debian based ditribution.<\/em><\/p>\n\n (If you want to install Discourse for production use, see our install guide<\/a>)<\/em><\/p>\n\nInstall Discourse Dependencies<\/h2>\n\n