diff --git a/Gemfile b/Gemfile
index fe9faf36a4..f728eef550 100644
--- a/Gemfile
+++ b/Gemfile
@@ -36,21 +36,12 @@ gem 'mail', require: false
gem 'mini_mime'
gem 'mini_suffix'
-gem 'hiredis'
-
-# holding off redis upgrade temporarily as it is having issues with our current
-# freedom patch, we will follow this up.
-#
-# FrozenError: can't modify frozen Hash
-# /var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.1.0/lib/redis/client.rb:93:in `delete'
-# /var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.1.0/lib/redis/client.rb:93:in `initialize'
-# /var/www/discourse/lib/freedom_patches/redis.rb:7:in `initialize'
-gem 'redis', '4.0.1', require: ["redis", "redis/connection/hiredis"]
+gem 'redis', '4.1.3'
gem 'redis-namespace'
gem 'active_model_serializers', '~> 0.8.3'
-gem 'onebox', '1.9.17'
+gem 'onebox', '1.9.21'
gem 'http_accept_language', '~>2.0.5', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 89de47af23..4176a30f6e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -143,7 +143,6 @@ GEM
hashdiff (0.3.9)
hashie (3.6.0)
highline (1.7.10)
- hiredis (0.6.3)
hkdf (0.3.0)
htmlentities (4.3.4)
http_accept_language (2.0.5)
@@ -173,7 +172,7 @@ GEM
logstash-event (1.2.02)
logstash-logger (0.26.1)
logstash-event (~> 1.2)
- logster (2.3.3)
+ logster (2.4.1)
loofah (2.2.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
@@ -183,7 +182,7 @@ GEM
mini_mime (>= 0.1.1)
maxminddb (0.1.22)
memory_profiler (0.9.13)
- message_bus (2.2.2)
+ message_bus (2.2.3)
rack (>= 1.1.3)
metaclass (0.0.4)
method_source (0.9.2)
@@ -200,7 +199,6 @@ GEM
mocha (1.8.0)
metaclass (~> 0.0.1)
mock_redis (0.19.0)
- moneta (1.1.1)
msgpack (1.2.10)
multi_json (1.13.1)
multi_xml (0.6.0)
@@ -245,9 +243,8 @@ GEM
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
- onebox (1.9.17)
+ onebox (1.9.21)
htmlentities (~> 4.3)
- moneta (~> 1.0)
multi_json (~> 1.11)
mustache
nokogiri (~> 1.7)
@@ -274,7 +271,7 @@ GEM
puma (3.12.1)
r2 (0.2.7)
rack (2.0.7)
- rack-mini-profiler (1.1.0)
+ rack-mini-profiler (1.1.3)
rack (>= 1.2.0)
rack-openid (1.3.1)
rack (>= 1.1.0)
@@ -310,7 +307,7 @@ GEM
msgpack (>= 0.4.3)
optimist (>= 3.0.0)
rchardet (1.8.0)
- redis (4.0.1)
+ redis (4.1.3)
redis-namespace (1.6.0)
redis (>= 3.0.4)
request_store (1.4.1)
@@ -467,7 +464,6 @@ DEPENDENCIES
flamegraph
gc_tracer
highline (~> 1.7.0)
- hiredis
htmlentities
http_accept_language (~> 2.0.5)
listen
@@ -501,7 +497,7 @@ DEPENDENCIES
omniauth-oauth2
omniauth-openid
omniauth-twitter
- onebox (= 1.9.17)
+ onebox (= 1.9.21)
openid-redis-store
parallel_tests
pg
@@ -518,7 +514,7 @@ DEPENDENCIES
rb-inotify (~> 0.9)
rbtrace
rchardet
- redis (= 4.0.1)
+ redis (= 4.1.3)
redis-namespace
rinku
rotp
diff --git a/app/assets/javascripts/admin/adapters/api-key.js.es6 b/app/assets/javascripts/admin/adapters/api-key.js.es6
new file mode 100644
index 0000000000..a473f66e08
--- /dev/null
+++ b/app/assets/javascripts/admin/adapters/api-key.js.es6
@@ -0,0 +1,11 @@
+import RESTAdapter from "discourse/adapters/rest";
+
+export default RESTAdapter.extend({
+ basePath() {
+ return "/admin/api/";
+ },
+
+ apiNameFor() {
+ return "key";
+ }
+});
diff --git a/app/assets/javascripts/admin/adapters/tag-group.js.es6 b/app/assets/javascripts/admin/adapters/tag-group.js.es6
new file mode 100644
index 0000000000..2e950aa2c1
--- /dev/null
+++ b/app/assets/javascripts/admin/adapters/tag-group.js.es6
@@ -0,0 +1,5 @@
+import RestAdapter from "discourse/adapters/rest";
+
+export default RestAdapter.extend({
+ jsonMode: true
+});
diff --git a/app/assets/javascripts/admin/components/ace-editor.js.es6 b/app/assets/javascripts/admin/components/ace-editor.js.es6
index 8fd9089b2e..60498a0bdb 100644
--- a/app/assets/javascripts/admin/components/ace-editor.js.es6
+++ b/app/assets/javascripts/admin/components/ace-editor.js.es6
@@ -1,7 +1,9 @@
+import Component from "@ember/component";
import loadScript from "discourse/lib/load-script";
import { observes } from "ember-addons/ember-computed-decorators";
+import { on } from "@ember/object/evented";
-export default Ember.Component.extend({
+export default Component.extend({
mode: "css",
classNames: ["ace-wrapper"],
_editor: null,
@@ -48,7 +50,7 @@ export default Ember.Component.extend({
}
},
- _destroyEditor: function() {
+ _destroyEditor: on("willDestroyElement", function() {
if (this._editor) {
this._editor.destroy();
this._editor = null;
@@ -59,7 +61,7 @@ export default Ember.Component.extend({
}
$(window).off("ace:resize");
- }.on("willDestroyElement"),
+ }),
resize() {
if (this._editor) {
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 5112564eec..ccacb2e705 100644
--- a/app/assets/javascripts/admin/components/admin-backups-logs.js.es6
+++ b/app/assets/javascripts/admin/components/admin-backups-logs.js.es6
@@ -1,10 +1,12 @@
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
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 { observes, on } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
classNames: ["admin-backups-logs"],
@@ -52,7 +54,7 @@ export default Ember.Component.extend(
// force rerender
this.rerenderBuffer();
- Ember.run.scheduleOnce("afterRender", this, this._scrollDown);
+ scheduleOnce("afterRender", this, this._scrollDown);
}, 150),
buildBuffer(buffer) {
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 f2480802b8..f110293a74 100644
--- a/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6
+++ b/app/assets/javascripts/admin/components/admin-directory-toggle.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
tagName: "th",
classNames: ["sortable"],
diff --git a/app/assets/javascripts/admin/components/admin-editable-field.js.es6 b/app/assets/javascripts/admin/components/admin-editable-field.js.es6
index 9d91e2a27f..f2785cffd4 100644
--- a/app/assets/javascripts/admin/components/admin-editable-field.js.es6
+++ b/app/assets/javascripts/admin/components/admin-editable-field.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "",
buffer: "",
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 5159168c30..b5f78c2a21 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,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
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 5949d51e24..be2e0f4e1a 100644
--- a/app/assets/javascripts/admin/components/admin-graph.js.es6
+++ b/app/assets/javascripts/admin/components/admin-graph.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import loadScript from "discourse/lib/load-script";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "canvas",
type: "line",
diff --git a/app/assets/javascripts/admin/components/admin-nav.js.es6 b/app/assets/javascripts/admin/components/admin-nav.js.es6
index 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/admin/components/admin-nav.js.es6
+++ b/app/assets/javascripts/admin/components/admin-nav.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/admin/components/admin-report-chart.js.es6 b/app/assets/javascripts/admin/components/admin-report-chart.js.es6
index 80d35c4693..f55288d9d2 100644
--- a/app/assets/javascripts/admin/components/admin-report-chart.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-chart.js.es6
@@ -1,7 +1,11 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { debounce } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import { number } from "discourse/lib/formatter";
import loadScript from "discourse/lib/load-script";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["admin-report-chart"],
limit: 8,
total: 0,
@@ -10,7 +14,7 @@ export default Ember.Component.extend({
this._super(...arguments);
this.resizeHandler = () =>
- Ember.run.debounce(this, this._scheduleChartRendering, 500);
+ debounce(this, this._scheduleChartRendering, 500);
},
didInsertElement() {
@@ -30,11 +34,11 @@ export default Ember.Component.extend({
didReceiveAttrs() {
this._super(...arguments);
- Ember.run.debounce(this, this._scheduleChartRendering, 100);
+ debounce(this, this._scheduleChartRendering, 100);
},
_scheduleChartRendering() {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
this._renderChart(
this.model,
this.element && this.element.querySelector(".chart-canvas")
@@ -46,10 +50,8 @@ export default Ember.Component.extend({
if (!chartCanvas) return;
const context = chartCanvas.getContext("2d");
- const chartData = Ember.makeArray(
- model.get("chartData") || model.get("data")
- );
- const prevChartData = Ember.makeArray(
+ const chartData = makeArray(model.get("chartData") || model.get("data"));
+ const prevChartData = makeArray(
model.get("prevChartData") || model.get("prev_data")
);
diff --git a/app/assets/javascripts/admin/components/admin-report-counters.js.es6 b/app/assets/javascripts/admin/components/admin-report-counters.js.es6
index d64bbe20fc..a66a3804c2 100644
--- a/app/assets/javascripts/admin/components/admin-report-counters.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-counters.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["admin-report-counters"],
attributeBindings: ["model.description:title"]
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 849d81460a..625dd669ee 100644
--- a/app/assets/javascripts/admin/components/admin-report-counts.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-counts.js.es6
@@ -1,7 +1,9 @@
-export default Ember.Component.extend({
+import { match } from "@ember/object/computed";
+import Component from "@ember/component";
+export default Component.extend({
allTime: true,
tagName: "tr",
- reverseColors: Ember.computed.match(
+ reverseColors: match(
"report.type",
/^(time_to_first_response|topics_with_no_response)$/
),
diff --git a/app/assets/javascripts/admin/components/admin-report-inline-table.js.es6 b/app/assets/javascripts/admin/components/admin-report-inline-table.js.es6
index 7e4933381c..38b3d4595e 100644
--- a/app/assets/javascripts/admin/components/admin-report-inline-table.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-inline-table.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["admin-report-inline-table"]
});
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 b7620b66cd..b644dbab9f 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,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "tr"
});
diff --git a/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6 b/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6
index 852bc92b3d..f28a2b348d 100644
--- a/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6
@@ -1,14 +1,18 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { debounce } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import { number } from "discourse/lib/formatter";
import loadScript from "discourse/lib/load-script";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["admin-report-chart", "admin-report-stacked-chart"],
init() {
this._super(...arguments);
this.resizeHandler = () =>
- Ember.run.debounce(this, this._scheduleChartRendering, 500);
+ debounce(this, this._scheduleChartRendering, 500);
},
didInsertElement() {
@@ -28,11 +32,11 @@ export default Ember.Component.extend({
didReceiveAttrs() {
this._super(...arguments);
- Ember.run.debounce(this, this._scheduleChartRendering, 100);
+ debounce(this, this._scheduleChartRendering, 100);
},
_scheduleChartRendering() {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
if (!this.element) {
return;
}
@@ -49,9 +53,7 @@ export default Ember.Component.extend({
const context = chartCanvas.getContext("2d");
- const chartData = Ember.makeArray(
- model.get("chartData") || model.get("data")
- );
+ const chartData = makeArray(model.get("chartData") || model.get("data"));
const data = {
labels: chartData[0].data.map(cd => cd.x),
diff --git a/app/assets/javascripts/admin/components/admin-report-storage-stats.js.es6 b/app/assets/javascripts/admin/components/admin-report-storage-stats.js.es6
index c4bf831f56..948ecf1e87 100644
--- a/app/assets/javascripts/admin/components/admin-report-storage-stats.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-storage-stats.js.es6
@@ -1,12 +1,14 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import { setting } from "discourse/lib/computed";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["admin-report-storage-stats"],
backupLocation: setting("backup_location"),
- backupStats: Ember.computed.alias("model.data.backups"),
- uploadStats: Ember.computed.alias("model.data.uploads"),
+ backupStats: alias("model.data.backups"),
+ uploadStats: alias("model.data.uploads"),
@computed("backupStats")
showBackupStats(stats) {
diff --git a/app/assets/javascripts/admin/components/admin-report-table-cell.js.es6 b/app/assets/javascripts/admin/components/admin-report-table-cell.js.es6
index 7140b69668..f83a33dbfb 100644
--- a/app/assets/javascripts/admin/components/admin-report-table-cell.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-table-cell.js.es6
@@ -1,6 +1,8 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "td",
classNames: ["admin-report-table-cell"],
classNameBindings: ["type", "property"],
@@ -11,8 +13,8 @@ export default Ember.Component.extend({
return label.compute(data, options || {});
},
- type: Ember.computed.alias("label.type"),
- property: Ember.computed.alias("label.mainProperty"),
- formatedValue: Ember.computed.alias("computedLabel.formatedValue"),
- value: Ember.computed.alias("computedLabel.value")
+ type: alias("label.type"),
+ property: alias("label.mainProperty"),
+ formatedValue: alias("computedLabel.formatedValue"),
+ value: alias("computedLabel.value")
});
diff --git a/app/assets/javascripts/admin/components/admin-report-table-header.js.es6 b/app/assets/javascripts/admin/components/admin-report-table-header.js.es6
index ab986f2946..9317ef1f66 100644
--- a/app/assets/javascripts/admin/components/admin-report-table-header.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-table-header.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "th",
classNames: ["admin-report-table-header"],
classNameBindings: ["label.mainProperty", "label.type", "isCurrentSort"],
diff --git a/app/assets/javascripts/admin/components/admin-report-table-row.js.es6 b/app/assets/javascripts/admin/components/admin-report-table-row.js.es6
index 3be140c308..c86f586a08 100644
--- a/app/assets/javascripts/admin/components/admin-report-table-row.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-table-row.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "tr",
classNames: ["admin-report-table-row"],
options: null
diff --git a/app/assets/javascripts/admin/components/admin-report-table.js.es6 b/app/assets/javascripts/admin/components/admin-report-table.js.es6
index 6e1e22c172..38e00c8ab8 100644
--- a/app/assets/javascripts/admin/components/admin-report-table.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report-table.js.es6
@@ -1,13 +1,16 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
const PAGES_LIMIT = 8;
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: ["sortable", "twoColumns"],
classNames: ["admin-report-table"],
sortable: false,
sortDirection: 1,
- perPage: Ember.computed.alias("options.perPage"),
+ perPage: alias("options.perPage"),
page: 0,
@computed("model.computedLabels.length")
@@ -89,7 +92,7 @@ export default Ember.Component.extend({
@computed("sortLabel", "sortDirection", "model.data.[]")
sortedData(sortLabel, sortDirection, data) {
- data = Ember.makeArray(data);
+ data = makeArray(data);
if (sortLabel) {
const compare = (label, direction) => {
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 b7620b66cd..b644dbab9f 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,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "tr"
});
diff --git a/app/assets/javascripts/admin/components/admin-report.js.es6 b/app/assets/javascripts/admin/components/admin-report.js.es6
index 37a8f2acc8..db06feecfc 100644
--- a/app/assets/javascripts/admin/components/admin-report.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report.js.es6
@@ -1,3 +1,8 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { alias, or, and, reads, equal, notEmpty } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import ReportLoader from "discourse/lib/reports-loader";
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
@@ -34,7 +39,7 @@ function collapseWeekly(data, average) {
return aggregate;
}
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: ["isEnabled", "isLoading", "dasherizedDataSourceName"],
classNames: ["admin-report"],
isEnabled: true,
@@ -54,12 +59,9 @@ export default Ember.Component.extend({
showHeader: true,
showTitle: true,
showFilteringUI: false,
- showDatesOptions: Ember.computed.alias("model.dates_filtering"),
- showRefresh: Ember.computed.or(
- "showDatesOptions",
- "model.available_filters.length"
- ),
- shouldDisplayTrend: Ember.computed.and("showTrend", "model.prev_period"),
+ showDatesOptions: alias("model.dates_filtering"),
+ showRefresh: or("showDatesOptions", "model.available_filters.length"),
+ shouldDisplayTrend: and("showTrend", "model.prev_period"),
init() {
this._super(...arguments);
@@ -67,8 +69,8 @@ export default Ember.Component.extend({
this._reports = [];
},
- startDate: Ember.computed.reads("filters.startDate"),
- endDate: Ember.computed.reads("filters.endDate"),
+ startDate: reads("filters.startDate"),
+ endDate: reads("filters.endDate"),
didReceiveAttrs() {
this._super(...arguments);
@@ -80,16 +82,12 @@ export default Ember.Component.extend({
}
},
- showError: Ember.computed.or(
- "showTimeoutError",
- "showExceptionError",
- "showNotFoundError"
- ),
- showNotFoundError: Ember.computed.equal("model.error", "not_found"),
- showTimeoutError: Ember.computed.equal("model.error", "timeout"),
- showExceptionError: Ember.computed.equal("model.error", "exception"),
+ showError: or("showTimeoutError", "showExceptionError", "showNotFoundError"),
+ showNotFoundError: equal("model.error", "not_found"),
+ showTimeoutError: equal("model.error", "timeout"),
+ showExceptionError: equal("model.error", "exception"),
- hasData: Ember.computed.notEmpty("model.data"),
+ hasData: notEmpty("model.data"),
@computed("dataSourceName", "model.type")
dasherizedDataSourceName(dataSourceName, type) {
@@ -111,7 +109,7 @@ export default Ember.Component.extend({
displayedModes(currentMode, reportModes, forcedModes) {
const modes = forcedModes ? forcedModes.split(",") : reportModes;
- return Ember.makeArray(modes).map(mode => {
+ return makeArray(modes).map(mode => {
const base = `btn-default mode-btn ${mode}`;
const cssClass = currentMode === mode ? `${base} is-current` : base;
@@ -311,7 +309,7 @@ export default Ember.Component.extend({
this.setProperties({ isLoading: true, rateLimitationString: null });
- Ember.run.next(() => {
+ next(() => {
let payload = this._buildPayload(["prev_period"]);
const callback = response => {
@@ -367,12 +365,12 @@ export default Ember.Component.extend({
_buildOptions(mode) {
if (mode === "table") {
const tableOptions = JSON.parse(JSON.stringify(TABLE_OPTIONS));
- return Ember.Object.create(
+ return EmberObject.create(
Object.assign(tableOptions, this.get("reportOptions.table") || {})
);
} else {
const chartOptions = JSON.parse(JSON.stringify(CHART_OPTIONS));
- return Ember.Object.create(
+ return EmberObject.create(
Object.assign(chartOptions, this.get("reportOptions.chart") || {})
);
}
diff --git a/app/assets/javascripts/admin/components/admin-theme-editor.js.es6 b/app/assets/javascripts/admin/components/admin-theme-editor.js.es6
index e54cb32c60..1dec9fce37 100644
--- a/app/assets/javascripts/admin/components/admin-theme-editor.js.es6
+++ b/app/assets/javascripts/admin/components/admin-theme-editor.js.es6
@@ -1,7 +1,9 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { fmt } from "discourse/lib/computed";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("theme.targets", "onlyOverridden", "showAdvanced")
visibleTargets(targets, onlyOverridden, showAdvanced) {
return targets.filter(target => {
@@ -82,7 +84,7 @@ export default Ember.Component.extend({
toggleMaximize: function() {
this.toggleProperty("maximized");
- Ember.run.next(() => this.appEvents.trigger("ace:resize"));
+ next(() => this.appEvents.trigger("ace:resize"));
},
onlyOverriddenChanged(value) {
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 1bf6128f1c..23bfac19b4 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,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import { empty } from "@ember/object/computed";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import UserField from "admin/models/user-field";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import { popupAjaxError } from "discourse/lib/ajax-error";
@@ -9,8 +13,8 @@ import {
on
} from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend(bufferedProperty("userField"), {
- editing: Ember.computed.empty("userField.id"),
+export default Component.extend(bufferedProperty("userField"), {
+ editing: empty("userField.id"),
classNameBindings: [":user-field"],
cantMoveUp: propertyEqual("userField", "firstField"),
@@ -27,7 +31,7 @@ export default Ember.Component.extend(bufferedProperty("userField"), {
@observes("editing")
_focusOnEdit() {
if (this.editing) {
- Ember.run.scheduleOnce("afterRender", this, "_focusName");
+ scheduleOnce("afterRender", this, "_focusName");
}
},
@@ -93,7 +97,7 @@ export default Ember.Component.extend(bufferedProperty("userField"), {
cancel() {
const id = this.get("userField.id");
- if (Ember.isEmpty(id)) {
+ if (isEmpty(id)) {
this.destroyAction(this.userField);
} else {
this.rollbackBuffer();
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 4da1828021..8a408cf166 100644
--- a/app/assets/javascripts/admin/components/admin-watched-word.js.es6
+++ b/app/assets/javascripts/admin/components/admin-watched-word.js.es6
@@ -1,8 +1,9 @@
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import { escapeExpression } from "discourse/lib/utilities";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
classNames: ["watched-word"],
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 7a6b5c13f1..1c7f6f05a0 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,8 +1,10 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["hook-event"],
- typeName: Ember.computed.alias("type.name"),
+ typeName: alias("type.name"),
@computed("typeName")
name(typeName) {
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 b558baa0b4..693e6502ff 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,9 +1,10 @@
+import Component from "@ember/component";
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({
+export default Component.extend({
tagName: "li",
expandDetails: null,
expandDetailsRequestKey: "request",
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 6e325b2fe9..0d8e80cc81 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,8 +1,9 @@
+import Component from "@ember/component";
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(
+export default Component.extend(
bufferedRender({
classes: ["text-muted", "text-danger", "text-successful", "text-muted"],
icons: ["far-circle", "times-circle", "circle", "circle"],
diff --git a/app/assets/javascripts/admin/components/admin-wrapper.js.es6 b/app/assets/javascripts/admin/components/admin-wrapper.js.es6
index 45daf32977..b60ac12855 100644
--- a/app/assets/javascripts/admin/components/admin-wrapper.js.es6
+++ b/app/assets/javascripts/admin/components/admin-wrapper.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
didInsertElement() {
this._super(...arguments);
$("body").addClass("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 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/admin/components/cancel-link.js.es6
+++ b/app/assets/javascripts/admin/components/cancel-link.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/admin/components/color-input.js.es6 b/app/assets/javascripts/admin/components/color-input.js.es6
index 17783cd36a..6c02f78dd5 100644
--- a/app/assets/javascripts/admin/components/color-input.js.es6
+++ b/app/assets/javascripts/admin/components/color-input.js.es6
@@ -1,3 +1,5 @@
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import { default as loadScript, loadCSS } from "discourse/lib/load-script";
/**
@@ -7,7 +9,7 @@ import { default as loadScript, loadCSS } from "discourse/lib/load-script";
@param brightnessValue is a number from 0 to 255 representing the brightness of the color. See ColorSchemeColor.
@params valid is a boolean indicating if the input field is a valid color.
**/
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["color-picker"],
hexValueChanged: function() {
var hex = this.hexValue;
@@ -36,7 +38,7 @@ export default Ember.Component.extend({
didInsertElement() {
loadScript("/javascripts/spectrum.js").then(() => {
loadCSS("/javascripts/spectrum.css").then(() => {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element.querySelector(".picker"))
.spectrum({ color: "#" + this.hexValue })
.on("change.spectrum", (me, color) => {
@@ -46,7 +48,7 @@ export default Ember.Component.extend({
});
});
});
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
this.hexValueChanged();
});
}
diff --git a/app/assets/javascripts/admin/components/email-styles-editor.js.es6 b/app/assets/javascripts/admin/components/email-styles-editor.js.es6
index d0e569421f..e465c04cba 100644
--- a/app/assets/javascripts/admin/components/email-styles-editor.js.es6
+++ b/app/assets/javascripts/admin/components/email-styles-editor.js.es6
@@ -1,7 +1,14 @@
+import { reads } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
- editorId: Ember.computed.reads("fieldName"),
+export default Component.extend({
+ editorId: reads("fieldName"),
+
+ @computed("fieldName")
+ currentEditorMode(fieldName) {
+ return fieldName === "css" ? "scss" : fieldName;
+ },
@computed("fieldName", "styles.html", "styles.css")
resetDisabled(fieldName) {
diff --git a/app/assets/javascripts/admin/components/embeddable-host.js.es6 b/app/assets/javascripts/admin/components/embeddable-host.js.es6
index 7639312ceb..57829b45fb 100644
--- a/app/assets/javascripts/admin/components/embeddable-host.js.es6
+++ b/app/assets/javascripts/admin/components/embeddable-host.js.es6
@@ -1,26 +1,30 @@
+import { isEmpty } from "@ember/utils";
+import { or } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
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 Component.extend(bufferedProperty("host"), {
editToggled: false,
tagName: "tr",
categoryId: null,
- editing: Ember.computed.or("host.isNew", "editToggled"),
+ editing: or("host.isNew", "editToggled"),
@on("didInsertElement")
@observes("editing")
_focusOnInput() {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
this.element.querySelector(".host-name").focus();
});
},
@computed("buffered.host", "host.isSaving")
cantSave(host, isSaving) {
- return isSaving || Ember.isEmpty(host);
+ return isSaving || isEmpty(host);
},
actions: {
diff --git a/app/assets/javascripts/admin/components/embedding-setting.js.es6 b/app/assets/javascripts/admin/components/embedding-setting.js.es6
index 4791e84e35..da7f9abb7f 100644
--- a/app/assets/javascripts/admin/components/embedding-setting.js.es6
+++ b/app/assets/javascripts/admin/components/embedding-setting.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["embed-setting"],
@computed("field")
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 ae6094c6a7..a6156a93ad 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,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["flag-user-lists"]
});
diff --git a/app/assets/javascripts/admin/components/highlighted-code.js.es6 b/app/assets/javascripts/admin/components/highlighted-code.js.es6
index 9f99c0929b..d182d7e2a1 100644
--- a/app/assets/javascripts/admin/components/highlighted-code.js.es6
+++ b/app/assets/javascripts/admin/components/highlighted-code.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { on, observes } from "ember-addons/ember-computed-decorators";
import highlightSyntax from "discourse/lib/highlight-syntax";
-export default Ember.Component.extend({
+export default Component.extend({
@on("didInsertElement")
@observes("code")
_refresh: function() {
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 a31b436167..e88c2bc3b7 100644
--- a/app/assets/javascripts/admin/components/inline-edit-checkbox.js.es6
+++ b/app/assets/javascripts/admin/components/inline-edit-checkbox.js.es6
@@ -1,9 +1,10 @@
+import Component from "@ember/component";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["inline-edit"],
checked: null,
diff --git a/app/assets/javascripts/admin/components/install-theme-item.js.es6 b/app/assets/javascripts/admin/components/install-theme-item.js.es6
index c1f3f57a8c..040760db01 100644
--- a/app/assets/javascripts/admin/components/install-theme-item.js.es6
+++ b/app/assets/javascripts/admin/components/install-theme-item.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["install-theme-item"]
});
diff --git a/app/assets/javascripts/admin/components/ip-lookup.js.es6 b/app/assets/javascripts/admin/components/ip-lookup.js.es6
index d4bf91ec6a..8438a4ee5c 100644
--- a/app/assets/javascripts/admin/components/ip-lookup.js.es6
+++ b/app/assets/javascripts/admin/components/ip-lookup.js.es6
@@ -1,9 +1,12 @@
+import EmberObject from "@ember/object";
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { ajax } from "discourse/lib/ajax";
import AdminUser from "admin/models/admin-user";
import copyText from "discourse/lib/copy-text";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["ip-lookup"],
@computed("other_accounts.length", "totalOthersWithSameIP")
@@ -20,7 +23,7 @@ export default Ember.Component.extend({
if (!this.location) {
ajax("/admin/users/ip-info", { data: { ip: this.ip } }).then(location =>
- this.set("location", Ember.Object.create(location))
+ this.set("location", EmberObject.create(location))
);
}
@@ -76,7 +79,7 @@ export default Ember.Component.extend({
$(document.body).append($copyRange);
if (copyText(text, $copyRange[0])) {
this.set("copied", true);
- Ember.run.later(() => this.set("copied", false), 2000);
+ later(() => this.set("copied", false), 2000);
}
$copyRange.remove();
},
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 b7620b66cd..b644dbab9f 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,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
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 e60393b3ba..8af1f83b16 100644
--- a/app/assets/javascripts/admin/components/penalty-post-action.js.es6
+++ b/app/assets/javascripts/admin/components/penalty-post-action.js.es6
@@ -1,8 +1,11 @@
+import { equal } from "@ember/object/computed";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
const ACTIONS = ["delete", "delete_replies", "edit", "none"];
-export default Ember.Component.extend({
+export default Component.extend({
postId: null,
postAction: null,
postEdit: null,
@@ -14,7 +17,7 @@ export default Ember.Component.extend({
});
},
- editing: Ember.computed.equal("postAction", "edit"),
+ editing: equal("postAction", "edit"),
actions: {
penaltyChanged() {
@@ -22,7 +25,7 @@ export default Ember.Component.extend({
// If we switch to edit mode, jump to the edit textarea
if (postAction === "edit") {
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
let elem = this.element;
let body = elem.closest(".modal-body");
body.scrollTop(body.height());
diff --git a/app/assets/javascripts/admin/components/permalink-form.js.es6 b/app/assets/javascripts/admin/components/permalink-form.js.es6
index 40ae69d090..b1f82ea295 100644
--- a/app/assets/javascripts/admin/components/permalink-form.js.es6
+++ b/app/assets/javascripts/admin/components/permalink-form.js.es6
@@ -1,8 +1,10 @@
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { fmt } from "discourse/lib/computed";
import Permalink from "admin/models/permalink";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["permalink-form"],
formSubmitted: false,
permalinkType: "topic_id",
@@ -19,7 +21,7 @@ export default Ember.Component.extend({
},
focusPermalink() {
- Ember.run.schedule("afterRender", () =>
+ schedule("afterRender", () =>
this.element.querySelector(".permalink-url").focus()
);
},
@@ -68,7 +70,7 @@ export default Ember.Component.extend({
didInsertElement() {
this._super(...arguments);
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element.querySelector(".external-url")).keydown(e => {
// enter key
if (e.keyCode === 13) {
diff --git a/app/assets/javascripts/admin/components/report-filters/filter.js.es6 b/app/assets/javascripts/admin/components/report-filters/filter.js.es6
index 25f2464f95..f61b2d496a 100644
--- a/app/assets/javascripts/admin/components/report-filters/filter.js.es6
+++ b/app/assets/javascripts/admin/components/report-filters/filter.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
actions: {
onChange(value) {
this.applyFilter(this.get("filter.id"), value);
diff --git a/app/assets/javascripts/admin/components/resumable-upload.js.es6 b/app/assets/javascripts/admin/components/resumable-upload.js.es6
index b9cab23040..d63a1a651d 100644
--- a/app/assets/javascripts/admin/components/resumable-upload.js.es6
+++ b/app/assets/javascripts/admin/components/resumable-upload.js.es6
@@ -1,3 +1,6 @@
+import { schedule } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import {
@@ -17,7 +20,7 @@ import {
uploadText="UPLOAD"
}}
**/
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
tagName: "button",
classNames: ["btn", "ru"],
@@ -44,18 +47,16 @@ export default Ember.Component.extend(
this.resumable.upload();
// mark as uploading
- Ember.run.later(() => this.set("isUploading", true));
+ later(() => this.set("isUploading", true));
});
this.resumable.on("fileProgress", file => {
// update progress
- Ember.run.later(() =>
- this.set("progress", parseInt(file.progress() * 100, 10))
- );
+ later(() => this.set("progress", parseInt(file.progress() * 100, 10)));
});
this.resumable.on("fileSuccess", file => {
- Ember.run.later(() => {
+ later(() => {
// mark as not uploading anymore
this._reset();
@@ -65,7 +66,7 @@ export default Ember.Component.extend(
});
this.resumable.on("fileError", (file, message) => {
- Ember.run.later(() => {
+ later(() => {
// mark as not uploading anymore
this._reset();
@@ -77,7 +78,7 @@ export default Ember.Component.extend(
@on("didInsertElement")
_assignBrowse() {
- Ember.run.schedule("afterRender", () =>
+ schedule("afterRender", () =>
this.resumable.assignBrowse($(this.element))
);
},
@@ -116,7 +117,7 @@ export default Ember.Component.extend(
click() {
if (this.isUploading) {
this.resumable.cancel();
- Ember.run.later(() => this._reset());
+ later(() => this._reset());
return false;
} else {
return true;
diff --git a/app/assets/javascripts/admin/components/save-controls.js.es6 b/app/assets/javascripts/admin/components/save-controls.js.es6
index cade010e5b..b039b0158c 100644
--- a/app/assets/javascripts/admin/components/save-controls.js.es6
+++ b/app/assets/javascripts/admin/components/save-controls.js.es6
@@ -1,9 +1,11 @@
+import { or } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["controls"],
- buttonDisabled: Ember.computed.or("model.isSaving", "saveDisabled"),
+ buttonDisabled: or("model.isSaving", "saveDisabled"),
@computed("model.isSaving")
savingText(saving) {
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 7fb246bf7a..8b6db57764 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
@@ -1,3 +1,5 @@
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
/**
A form to create an IP address that will be blocked or whitelisted.
Example usage:
@@ -13,7 +15,7 @@ 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({
+export default Component.extend({
classNames: ["screened-ip-address-form"],
formSubmitted: false,
actionName: "block",
@@ -61,7 +63,7 @@ export default Ember.Component.extend({
.then(result => {
this.setProperties({ ip_address: "", formSubmitted: false });
this.action(ScreenedIpAddress.create(result.screened_ip_address));
- Ember.run.schedule("afterRender", () =>
+ schedule("afterRender", () =>
this.element.querySelector(".ip-address-input").focus()
);
})
@@ -83,7 +85,7 @@ export default Ember.Component.extend({
@on("didInsertElement")
_init() {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element.querySelector(".ip-address-input")).keydown(e => {
if (e.keyCode === 13) {
this.send("submit");
diff --git a/app/assets/javascripts/admin/components/secret-value-list.js.es6 b/app/assets/javascripts/admin/components/secret-value-list.js.es6
index 58539cb916..4327f62f80 100644
--- a/app/assets/javascripts/admin/components/secret-value-list.js.es6
+++ b/app/assets/javascripts/admin/components/secret-value-list.js.es6
@@ -1,6 +1,9 @@
+import { isEmpty } from "@ember/utils";
+import Component from "@ember/component";
import { on } from "ember-addons/ember-computed-decorators";
+import { set } from "@ember/object";
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [":value-list", ":secret-value-list"],
inputDelimiter: null,
collection: null,
@@ -42,7 +45,7 @@ export default Ember.Component.extend({
_checkInvalidInput(inputs) {
this.set("validationMessage", null);
for (let input of inputs) {
- if (Ember.isEmpty(input) || input.includes("|")) {
+ if (isEmpty(input) || input.includes("|")) {
this.set(
"validationMessage",
I18n.t("admin.site_settings.secret_list.invalid_input")
@@ -65,7 +68,7 @@ export default Ember.Component.extend({
_replaceValue(index, newValue, keyName) {
let item = this.collection[index];
- Ember.set(item, keyName, newValue);
+ set(item, keyName, newValue);
this._saveValues();
},
diff --git a/app/assets/javascripts/admin/components/silence-details.js.es6 b/app/assets/javascripts/admin/components/silence-details.js.es6
index 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/admin/components/silence-details.js.es6
+++ b/app/assets/javascripts/admin/components/silence-details.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/admin/components/site-setting.js.es6 b/app/assets/javascripts/admin/components/site-setting.js.es6
index 78696c6e06..cd768407ff 100644
--- a/app/assets/javascripts/admin/components/site-setting.js.es6
+++ b/app/assets/javascripts/admin/components/site-setting.js.es6
@@ -1,10 +1,15 @@
+import Component from "@ember/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, {
+export default Component.extend(BufferedContent, SettingComponent, {
+ updateExistingUsers: null,
+
_save() {
const setting = this.buffered;
- return SiteSetting.update(setting.get("setting"), setting.get("value"));
+ return SiteSetting.update(setting.get("setting"), setting.get("value"), {
+ updateExistingUsers: this.updateExistingUsers
+ });
}
});
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 f46e965832..2b2fdaca8e 100644
--- a/app/assets/javascripts/admin/components/site-settings/bool.js.es6
+++ b/app/assets/javascripts/admin/components/site-settings/bool.js.es6
@@ -1,10 +1,12 @@
+import { isEmpty } from "@ember/utils";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("value")
enabled: {
get(value) {
- if (Ember.isEmpty(value)) {
+ if (isEmpty(value)) {
return false;
}
return value.toString() === "true";
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 36c712fa8d..d4476ddf13 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,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("value")
selectedCategories: {
get(value) {
diff --git a/app/assets/javascripts/admin/components/site-settings/group-list.js.es6 b/app/assets/javascripts/admin/components/site-settings/group-list.js.es6
index 0ab60a3436..21af030269 100644
--- a/app/assets/javascripts/admin/components/site-settings/group-list.js.es6
+++ b/app/assets/javascripts/admin/components/site-settings/group-list.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
@computed()
groupChoices() {
return this.site.get("groups").map(g => {
diff --git a/app/assets/javascripts/admin/components/site-settings/tag-list.js.es6 b/app/assets/javascripts/admin/components/site-settings/tag-list.js.es6
new file mode 100644
index 0000000000..417ad622cb
--- /dev/null
+++ b/app/assets/javascripts/admin/components/site-settings/tag-list.js.es6
@@ -0,0 +1,15 @@
+import Component from "@ember/component";
+import computed from "ember-addons/ember-computed-decorators";
+
+export default Component.extend({
+ @computed("value")
+ selectedTags: {
+ get(value) {
+ return value.split("|");
+ },
+ set(value) {
+ this.set("value", value.join("|"));
+ return value;
+ }
+ }
+});
diff --git a/app/assets/javascripts/admin/components/site-settings/uploaded-image-list.js.es6 b/app/assets/javascripts/admin/components/site-settings/uploaded-image-list.js.es6
index 57bd7fa49b..7e705321d0 100644
--- a/app/assets/javascripts/admin/components/site-settings/uploaded-image-list.js.es6
+++ b/app/assets/javascripts/admin/components/site-settings/uploaded-image-list.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import showModal from "discourse/lib/show-modal";
-export default Ember.Component.extend({
+export default Component.extend({
actions: {
showUploadModal({ value, setting }) {
showModal("admin-uploaded-image-list", {
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 da6dda43f8..4467a092d1 100644
--- a/app/assets/javascripts/admin/components/site-text-summary.js.es6
+++ b/app/assets/javascripts/admin/components/site-text-summary.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { on } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["site-text"],
classNameBindings: ["siteText.overridden"],
diff --git a/app/assets/javascripts/admin/components/staff-actions.js.es6 b/app/assets/javascripts/admin/components/staff-actions.js.es6
index 5c7da1dc9d..1c295799dd 100644
--- a/app/assets/javascripts/admin/components/staff-actions.js.es6
+++ b/app/assets/javascripts/admin/components/staff-actions.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import DiscourseURL from "discourse/lib/url";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["table", "staff-actions"],
willDestroyElement() {
diff --git a/app/assets/javascripts/admin/components/suspension-details.js.es6 b/app/assets/javascripts/admin/components/suspension-details.js.es6
index 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/admin/components/suspension-details.js.es6
+++ b/app/assets/javascripts/admin/components/suspension-details.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/admin/components/tags-uploader.js.es6 b/app/assets/javascripts/admin/components/tags-uploader.js.es6
index 1373792f24..88f4afc8d9 100644
--- a/app/assets/javascripts/admin/components/tags-uploader.js.es6
+++ b/app/assets/javascripts/admin/components/tags-uploader.js.es6
@@ -1,9 +1,11 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import UploadMixin from "discourse/mixins/upload";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
type: "csv",
uploadUrl: "/tags/upload",
- addDisabled: Ember.computed.alias("uploading"),
+ addDisabled: alias("uploading"),
elementId: "tag-uploader",
validateUploadedFilesOptions() {
diff --git a/app/assets/javascripts/admin/components/theme-setting-editor.js.es6 b/app/assets/javascripts/admin/components/theme-setting-editor.js.es6
index 5a764e55eb..e0ebe6ccdd 100644
--- a/app/assets/javascripts/admin/components/theme-setting-editor.js.es6
+++ b/app/assets/javascripts/admin/components/theme-setting-editor.js.es6
@@ -1,10 +1,11 @@
+import Component from "@ember/component";
import BufferedContent from "discourse/mixins/buffered-content";
import SettingComponent from "admin/mixins/setting-component";
import { ajax } from "discourse/lib/ajax";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Component.extend(BufferedContent, SettingComponent, {
+export default Component.extend(BufferedContent, SettingComponent, {
layoutName: "admin/templates/components/site-setting",
+
_save() {
return ajax(`/admin/themes/${this.model.id}/setting`, {
type: "PUT",
@@ -12,6 +13,6 @@ export default Ember.Component.extend(BufferedContent, SettingComponent, {
name: this.setting.setting,
value: this.get("buffered.value")
}
- }).catch(popupAjaxError);
+ });
}
});
diff --git a/app/assets/javascripts/admin/components/theme-translation.js.es6 b/app/assets/javascripts/admin/components/theme-translation.js.es6
index ab29ac2312..361df489af 100644
--- a/app/assets/javascripts/admin/components/theme-translation.js.es6
+++ b/app/assets/javascripts/admin/components/theme-translation.js.es6
@@ -1,11 +1,13 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import BufferedContent from "discourse/mixins/buffered-content";
import SettingComponent from "admin/mixins/setting-component";
-export default Ember.Component.extend(BufferedContent, SettingComponent, {
+export default Component.extend(BufferedContent, SettingComponent, {
layoutName: "admin/templates/components/site-setting",
- setting: Ember.computed.alias("translation"),
+ setting: alias("translation"),
type: "string",
- settingName: Ember.computed.alias("translation.key"),
+ settingName: alias("translation.key"),
_save() {
return this.model.saveTranslation(
diff --git a/app/assets/javascripts/admin/components/themes-list-item.js.es6 b/app/assets/javascripts/admin/components/themes-list-item.js.es6
index 7bafa95c21..af30e5a398 100644
--- a/app/assets/javascripts/admin/components/themes-list-item.js.es6
+++ b/app/assets/javascripts/admin/components/themes-list-item.js.es6
@@ -1,3 +1,6 @@
+import { gt, and } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes
@@ -7,13 +10,13 @@ import { escape } from "pretty-text/sanitizer";
const MAX_COMPONENTS = 4;
-export default Ember.Component.extend({
+export default Component.extend({
childrenExpanded: false,
classNames: ["themes-list-item"],
classNameBindings: ["theme.selected:selected"],
- hasComponents: Ember.computed.gt("children.length", 0),
- displayComponents: Ember.computed.and("hasComponents", "theme.isActive"),
- displayHasMore: Ember.computed.gt("theme.childThemes.length", MAX_COMPONENTS),
+ hasComponents: gt("children.length", 0),
+ displayComponents: and("hasComponents", "theme.isActive"),
+ displayHasMore: gt("theme.childThemes.length", MAX_COMPONENTS),
click(e) {
if (!$(e.target).hasClass("others-count")) {
@@ -32,7 +35,7 @@ export default Ember.Component.extend({
},
scheduleAnimation() {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
this.animate(true);
});
},
diff --git a/app/assets/javascripts/admin/components/themes-list.js.es6 b/app/assets/javascripts/admin/components/themes-list.js.es6
index d306bab11c..357e4f756c 100644
--- a/app/assets/javascripts/admin/components/themes-list.js.es6
+++ b/app/assets/javascripts/admin/components/themes-list.js.es6
@@ -1,18 +1,20 @@
+import { gt, equal } from "@ember/object/computed";
+import Component from "@ember/component";
import { THEMES, COMPONENTS } from "admin/models/theme";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
THEMES: THEMES,
COMPONENTS: COMPONENTS,
classNames: ["themes-list"],
- hasThemes: Ember.computed.gt("themesList.length", 0),
- hasActiveThemes: Ember.computed.gt("activeThemes.length", 0),
- hasInactiveThemes: Ember.computed.gt("inactiveThemes.length", 0),
+ hasThemes: gt("themesList.length", 0),
+ hasActiveThemes: gt("activeThemes.length", 0),
+ hasInactiveThemes: gt("inactiveThemes.length", 0),
- themesTabActive: Ember.computed.equal("currentTab", THEMES),
- componentsTabActive: Ember.computed.equal("currentTab", COMPONENTS),
+ themesTabActive: equal("currentTab", THEMES),
+ componentsTabActive: equal("currentTab", COMPONENTS),
@computed("themes", "components", "currentTab")
themesList(themes, components) {
diff --git a/app/assets/javascripts/admin/components/value-list.js.es6 b/app/assets/javascripts/admin/components/value-list.js.es6
index ff93375260..31ef93932e 100644
--- a/app/assets/javascripts/admin/components/value-list.js.es6
+++ b/app/assets/javascripts/admin/components/value-list.js.es6
@@ -1,17 +1,20 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { empty, alias } from "@ember/object/computed";
+import Component from "@ember/component";
import { on } from "ember-addons/ember-computed-decorators";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [":value-list"],
- inputInvalid: Ember.computed.empty("newValue"),
+ inputInvalid: empty("newValue"),
inputDelimiter: null,
inputType: null,
newValue: "",
collection: null,
values: null,
- noneKey: Ember.computed.alias("addKey"),
+ noneKey: alias("addKey"),
@on("didReceiveAttrs")
_setupCollection() {
@@ -29,7 +32,7 @@ export default Ember.Component.extend({
@computed("choices.[]", "collection.[]")
filteredChoices(choices, collection) {
- return Ember.makeArray(choices).filter(i => collection.indexOf(i) < 0);
+ return makeArray(choices).filter(i => collection.indexOf(i) < 0);
},
keyDown(event) {
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 b56f2c423c..629c5a2b6a 100644
--- a/app/assets/javascripts/admin/components/watched-word-form.js.es6
+++ b/app/assets/javascripts/admin/components/watched-word-form.js.es6
@@ -1,3 +1,6 @@
+import { isEmpty } from "@ember/utils";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import WatchedWord from "admin/models/watched-word";
import {
default as computed,
@@ -5,7 +8,7 @@ import {
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["watched-word-form"],
formSubmitted: false,
actionKey: null,
@@ -21,7 +24,7 @@ export default Ember.Component.extend({
@observes("word")
removeMessage() {
- if (this.showMessage && !Ember.isEmpty(this.word)) {
+ if (this.showMessage && !isEmpty(this.word)) {
this.set("showMessage", false);
}
},
@@ -63,7 +66,7 @@ export default Ember.Component.extend({
message: I18n.t("admin.watched_words.form.success")
});
this.action(WatchedWord.create(result));
- Ember.run.schedule("afterRender", () =>
+ schedule("afterRender", () =>
this.element.querySelector(".watched-word-input").focus()
);
})
@@ -85,7 +88,7 @@ export default Ember.Component.extend({
@on("didInsertElement")
_init() {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element.querySelector(".watched-word-input")).keydown(e => {
if (e.keyCode === 13) {
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 b1706337f2..417f3d5bbf 100644
--- a/app/assets/javascripts/admin/components/watched-word-uploader.js.es6
+++ b/app/assets/javascripts/admin/components/watched-word-uploader.js.es6
@@ -1,11 +1,13 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import UploadMixin from "discourse/mixins/upload";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
type: "txt",
classNames: "watched-words-uploader",
uploadUrl: "/admin/logs/watched_words/upload",
- addDisabled: Ember.computed.alias("uploading"),
+ addDisabled: alias("uploading"),
validateUploadedFilesOptions() {
return { skipValidation: true };
diff --git a/app/assets/javascripts/admin/controllers/admin-api-keys-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-api-keys-index.js.es6
new file mode 100644
index 0000000000..b087269626
--- /dev/null
+++ b/app/assets/javascripts/admin/controllers/admin-api-keys-index.js.es6
@@ -0,0 +1,13 @@
+import { popupAjaxError } from "discourse/lib/ajax-error";
+
+export default Ember.Controller.extend({
+ actions: {
+ revokeKey(key) {
+ key.revoke().catch(popupAjaxError);
+ },
+
+ undoRevokeKey(key) {
+ key.undoRevoke().catch(popupAjaxError);
+ }
+ }
+});
diff --git a/app/assets/javascripts/admin/controllers/admin-api-keys-new.js.es6 b/app/assets/javascripts/admin/controllers/admin-api-keys-new.js.es6
new file mode 100644
index 0000000000..f4d56c0a05
--- /dev/null
+++ b/app/assets/javascripts/admin/controllers/admin-api-keys-new.js.es6
@@ -0,0 +1,39 @@
+import { default as computed } from "ember-addons/ember-computed-decorators";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+
+export default Ember.Controller.extend({
+ userModes: [
+ { id: "all", name: I18n.t("admin.api.all_users") },
+ { id: "single", name: I18n.t("admin.api.single_user") }
+ ],
+
+ @computed("userMode")
+ showUserSelector(mode) {
+ return mode === "single";
+ },
+
+ @computed("model.description", "model.username", "userMode")
+ saveDisabled(description, username, userMode) {
+ if (Ember.isBlank(description)) return true;
+ if (userMode === "single" && Ember.isBlank(username)) return true;
+ return false;
+ },
+
+ actions: {
+ changeUserMode(value) {
+ if (value === "all") {
+ this.model.set("username", null);
+ }
+ this.set("userMode", value);
+ },
+
+ save() {
+ this.model
+ .save()
+ .then(() => {
+ this.transitionToRoute("adminApiKeys.show", this.model.id);
+ })
+ .catch(popupAjaxError);
+ }
+ }
+});
diff --git a/app/assets/javascripts/admin/controllers/admin-api-keys-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-api-keys-show.js.es6
new file mode 100644
index 0000000000..2e19ea5779
--- /dev/null
+++ b/app/assets/javascripts/admin/controllers/admin-api-keys-show.js.es6
@@ -0,0 +1,54 @@
+import { bufferedProperty } from "discourse/mixins/buffered-content";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import { empty } from "@ember/object/computed";
+
+export default Ember.Controller.extend(bufferedProperty("model"), {
+ isNew: empty("model.id"),
+
+ actions: {
+ saveDescription() {
+ const buffered = this.buffered;
+ const attrs = buffered.getProperties("description");
+
+ this.model
+ .save(attrs)
+ .then(() => {
+ this.set("editingDescription", false);
+ this.rollbackBuffer();
+ })
+ .catch(popupAjaxError);
+ },
+
+ cancel() {
+ const id = this.get("userField.id");
+ if (Ember.isEmpty(id)) {
+ this.destroyAction(this.userField);
+ } else {
+ this.rollbackBuffer();
+ this.set("editing", false);
+ }
+ },
+
+ editDescription() {
+ this.toggleProperty("editingDescription");
+ if (!this.editingDescription) {
+ this.rollbackBuffer();
+ }
+ },
+
+ revokeKey(key) {
+ key.revoke().catch(popupAjaxError);
+ },
+
+ deleteKey(key) {
+ key
+ .destroyRecord()
+ .then(() => this.transitionToRoute("adminApiKeys.index"))
+ .catch(popupAjaxError);
+ },
+
+ undoRevokeKey(key) {
+ key.undoRevoke().catch(popupAjaxError);
+ }
+ }
+});
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 87b26f5ef1..e69de29bb2 100644
--- a/app/assets/javascripts/admin/controllers/admin-api-keys.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-api-keys.js.es6
@@ -1,41 +0,0 @@
-import ApiKey from "admin/models/api-key";
-import { default as computed } from "ember-addons/ember-computed-decorators";
-
-export default Ember.Controller.extend({
- @computed("model.[]")
- hasMasterKey(model) {
- return !!model.findBy("user", null);
- },
-
- actions: {
- generateMasterKey() {
- ApiKey.generateMasterKey().then(key => this.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();
- }
- }
- );
- },
-
- 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.model.removeObject(key));
- }
- }
- );
- }
- }
-});
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 684f844bc5..6b69eaea72 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,16 @@
+import { alias, equal } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { setting, i18n } from "discourse/lib/computed";
-export default Ember.Controller.extend({
- adminBackups: Ember.inject.controller(),
- status: Ember.computed.alias("adminBackups.model"),
+export default Controller.extend({
+ adminBackups: inject(),
+ status: alias("adminBackups.model"),
uploadLabel: i18n("admin.backups.upload.label"),
backupLocation: setting("backup_location"),
- localBackupStorage: Ember.computed.equal("backupLocation", "local"),
+ localBackupStorage: equal("backupLocation", "local"),
@computed("status.allowRestore", "status.isOperationRunning")
restoreTitle(allowRestore, isOperationRunning) {
diff --git a/app/assets/javascripts/admin/controllers/admin-backups-logs.js.es6 b/app/assets/javascripts/admin/controllers/admin-backups-logs.js.es6
index 40bad8ae00..a32e216255 100644
--- a/app/assets/javascripts/admin/controllers/admin-backups-logs.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-backups-logs.js.es6
@@ -1,6 +1,9 @@
-export default Ember.Controller.extend({
- adminBackups: Ember.inject.controller(),
- status: Ember.computed.alias("adminBackups.model"),
+import { alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
+export default Controller.extend({
+ adminBackups: inject(),
+ status: alias("adminBackups.model"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/admin/controllers/admin-backups.js.es6 b/app/assets/javascripts/admin/controllers/admin-backups.js.es6
index 5cfa57271e..7e942d9e9c 100644
--- a/app/assets/javascripts/admin/controllers/admin-backups.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-backups.js.es6
@@ -1,9 +1,11 @@
-export default Ember.Controller.extend({
- noOperationIsRunning: Ember.computed.not("model.isOperationRunning"),
- rollbackEnabled: Ember.computed.and(
+import { not, and } from "@ember/object/computed";
+import Controller from "@ember/controller";
+export default Controller.extend({
+ noOperationIsRunning: not("model.isOperationRunning"),
+ rollbackEnabled: and(
"model.canRollback",
"model.restoreEnabled",
"noOperationIsRunning"
),
- rollbackDisabled: Ember.computed.not("rollbackEnabled")
+ rollbackDisabled: 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 1f7382f54b..733f4589fe 100644
--- a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6
@@ -1,21 +1,22 @@
+import { alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import { propertyNotEqual } from "discourse/lib/computed";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(bufferedProperty("model"), {
- adminBadges: Ember.inject.controller(),
+export default Controller.extend(bufferedProperty("model"), {
+ adminBadges: inject(),
saving: false,
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: alias("adminBadges.badgeTypes"),
+ badgeGroupings: alias("adminBadges.badgeGroupings"),
+ badgeTriggers: alias("adminBadges.badgeTriggers"),
+ protectedSystemFields: alias("adminBadges.protectedSystemFields"),
- readOnly: Ember.computed.alias("buffered.system"),
+ readOnly: alias("buffered.system"),
showDisplayName: propertyNotEqual("name", "displayName"),
@computed("model.query", "buffered.query")
diff --git a/app/assets/javascripts/admin/controllers/admin-badges.js.es6 b/app/assets/javascripts/admin/controllers/admin-badges.js.es6
index 77c79b724a..cf6c4e3aa2 100644
--- a/app/assets/javascripts/admin/controllers/admin-badges.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-badges.js.es6
@@ -1 +1,2 @@
-export default Ember.Controller.extend();
+import Controller from "@ember/controller";
+export default Controller.extend();
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 3fbdb989cf..ce99c2cfea 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,6 +1,8 @@
+import { later } from "@ember/runloop";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
@computed("model.colors", "onlyOverridden")
colors(allColors, onlyOverridden) {
if (onlyOverridden) {
@@ -40,7 +42,7 @@ export default Ember.Controller.extend({
);
}
- Ember.run.later(() => {
+ later(() => {
this.set("model.savingStatus", null);
}, 2000);
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 7a9be8cc5d..21c628be24 100644
--- a/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-customize-colors.js.es6
@@ -1,7 +1,9 @@
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
import showModal from "discourse/lib/show-modal";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
@computed("model.@each.id")
baseColorScheme() {
return this.model.findBy("is_base", true);
@@ -14,7 +16,7 @@ export default Ember.Controller.extend({
@computed("baseColorScheme")
baseColors(baseColorScheme) {
- const baseColorsHash = Ember.Object.create({});
+ const baseColorsHash = EmberObject.create({});
baseColorScheme.get("colors").forEach(color => {
baseColorsHash.set(color.get("name"), color);
});
diff --git a/app/assets/javascripts/admin/controllers/admin-customize-email-style-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-email-style-edit.js.es6
index b8054c8bc3..f48f46eff0 100644
--- a/app/assets/javascripts/admin/controllers/admin-customize-email-style-edit.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-customize-email-style-edit.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
@computed("model.isSaving")
saveButtonText(isSaving) {
return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save");
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 68a78a7d7f..5ec405594a 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,8 +1,9 @@
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(bufferedProperty("emailTemplate"), {
+export default Controller.extend(bufferedProperty("emailTemplate"), {
saved: false,
@computed("buffered.body", "buffered.subject")
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 8631babc67..2f85e8418d 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,8 @@
-export default Ember.Controller.extend({
+import { sort } from "@ember/object/computed";
+import Controller from "@ember/controller";
+export default Controller.extend({
emailTemplates: null,
- sortedTemplates: Ember.computed.sort("emailTemplates", "titleSorting"),
+ sortedTemplates: sort("emailTemplates", "titleSorting"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/admin/controllers/admin-customize-robots-txt.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-robots-txt.js.es6
index 9cb38c75ea..5c6d2499f4 100644
--- a/app/assets/javascripts/admin/controllers/admin-customize-robots-txt.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-customize-robots-txt.js.es6
@@ -1,12 +1,14 @@
+import { not } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import { propertyEqual } from "discourse/lib/computed";
-export default Ember.Controller.extend(bufferedProperty("model"), {
+export default Controller.extend(bufferedProperty("model"), {
saved: false,
isSaving: false,
saveDisabled: propertyEqual("model.robots_txt", "buffered.robots_txt"),
- resetDisbaled: Ember.computed.not("model.overridden"),
+ resetDisbaled: not("model.overridden"),
actions: {
save() {
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 ba54e3c91f..a5a286bf80 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,7 +1,8 @@
+import Controller from "@ember/controller";
import { url } from "discourse/lib/computed";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
section: null,
currentTarget: 0,
maximized: false,
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 fc211ce628..d4622e21d8 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,3 +1,6 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { empty, notEmpty, match } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { url } from "discourse/lib/computed";
import { popupAjaxError } from "discourse/lib/ajax-error";
@@ -7,10 +10,10 @@ import { THEMES, COMPONENTS } from "admin/models/theme";
const THEME_UPLOAD_VAR = 2;
-export default Ember.Controller.extend({
+export default Controller.extend({
downloadUrl: url("model.id", "/admin/customize/themes/%@/export"),
previewUrl: url("model.id", "/admin/themes/%@/preview"),
- addButtonDisabled: Ember.computed.empty("selectedChildThemeId"),
+ addButtonDisabled: empty("selectedChildThemeId"),
editRouteName: "adminCustomizeThemes.edit",
@computed("model.editedFields")
@@ -79,14 +82,14 @@ export default Ember.Controller.extend({
return settings.map(setting => ThemeSettings.create(setting));
},
- hasSettings: Ember.computed.notEmpty("settings"),
+ hasSettings: notEmpty("settings"),
@computed("model.translations")
translations(translations) {
return translations.map(setting => ThemeSettings.create(setting));
},
- hasTranslations: Ember.computed.notEmpty("translations"),
+ hasTranslations: notEmpty("translations"),
@computed("model.remoteError", "updatingRemote")
showRemoteError(errorMessage, updating) {
@@ -124,8 +127,8 @@ export default Ember.Controller.extend({
});
this.get("parentController.model.content").forEach(theme => {
- const children = Ember.makeArray(theme.get("childThemes"));
- const rawChildren = Ember.makeArray(theme.get("child_themes"));
+ const children = makeArray(theme.get("childThemes"));
+ const rawChildren = makeArray(theme.get("child_themes"));
const index = children ? children.indexOf(model) : -1;
if (index > -1) {
children.splice(index, 1);
@@ -147,10 +150,7 @@ export default Ember.Controller.extend({
"scss"
);
},
- sourceIsHttp: Ember.computed.match(
- "model.remote_theme.remote_url",
- /^http(s)?:\/\//
- ),
+ sourceIsHttp: match("model.remote_theme.remote_url", /^http(s)?:\/\//),
actions: {
updateToLatest() {
this.set("updatingRemote", true);
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 f38ae3ab74..6727df97f3 100644
--- a/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-customize-themes.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { THEMES } from "admin/models/theme";
-export default Ember.Controller.extend({
+export default Controller.extend({
currentTab: THEMES,
@computed("model", "model.@each.component")
diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-general.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard-general.js.es6
index eb85ef4a41..24884b0ba6 100644
--- a/app/assets/javascripts/admin/controllers/admin-dashboard-general.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-dashboard-general.js.es6
@@ -1,3 +1,6 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { setting } from "discourse/lib/computed";
import computed from "ember-addons/ember-computed-decorators";
import AdminDashboard from "admin/models/admin-dashboard";
@@ -6,16 +9,14 @@ import PeriodComputationMixin from "admin/mixins/period-computation";
function staticReport(reportType) {
return Ember.computed("reports.[]", function() {
- return Ember.makeArray(this.reports).find(
- report => report.type === reportType
- );
+ return makeArray(this.reports).find(report => report.type === reportType);
});
}
-export default Ember.Controller.extend(PeriodComputationMixin, {
+export default Controller.extend(PeriodComputationMixin, {
isLoading: false,
dashboardFetchedAt: null,
- exceptionController: Ember.inject.controller("exception"),
+ exceptionController: inject("exception"),
logSearchQueriesEnabled: setting("log_search_queries"),
basePath: Discourse.BaseUri,
@@ -93,7 +94,7 @@ export default Ember.Controller.extend(PeriodComputationMixin, {
this.setProperties({
dashboardFetchedAt: new Date(),
model: adminDashboardModel,
- reports: Ember.makeArray(adminDashboardModel.reports).map(x =>
+ reports: makeArray(adminDashboardModel.reports).map(x =>
Report.create(x)
)
});
diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js.es6
index df06e682f4..e5d8dae25a 100644
--- a/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import PeriodComputationMixin from "admin/mixins/period-computation";
-export default Ember.Controller.extend(PeriodComputationMixin, {
+export default Controller.extend(PeriodComputationMixin, {
@computed
flagsStatusOptions() {
return {
diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js.es6
index 9c2eccdab1..b582f733aa 100644
--- a/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js.es6
@@ -1,7 +1,9 @@
+import { debounce } from "@ember/runloop";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
const { get } = Ember;
-export default Ember.Controller.extend({
+export default Controller.extend({
filter: null,
@computed("model.[]", "filter")
@@ -20,7 +22,7 @@ export default Ember.Controller.extend({
actions: {
filterReports(filter) {
- Ember.run.debounce(this, this._performFiltering, filter, 250);
+ debounce(this, this._performFiltering, filter, 250);
}
},
diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6 b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
index 0ff4b540d1..0f214d6f2d 100644
--- a/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-dashboard.js.es6
@@ -1,3 +1,5 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { setting } from "discourse/lib/computed";
import computed from "ember-addons/ember-computed-decorators";
import AdminDashboard from "admin/models/admin-dashboard";
@@ -5,10 +7,10 @@ import VersionCheck from "admin/models/version-check";
const PROBLEMS_CHECK_MINUTES = 1;
-export default Ember.Controller.extend({
+export default Controller.extend({
isLoading: false,
dashboardFetchedAt: null,
- exceptionController: Ember.inject.controller("exception"),
+ exceptionController: inject("exception"),
showVersionChecks: setting("version_checks"),
@computed("problems.length")
diff --git a/app/assets/javascripts/admin/controllers/admin-email-advanced-test.js.es6 b/app/assets/javascripts/admin/controllers/admin-email-advanced-test.js.es6
index c98fb7cfb9..8443344349 100644
--- a/app/assets/javascripts/admin/controllers/admin-email-advanced-test.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-email-advanced-test.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
email: null,
text: null,
elided: null,
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 02860948c0..124c364af3 100644
--- a/app/assets/javascripts/admin/controllers/admin-email-index.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-email-index.js.es6
@@ -1,11 +1,13 @@
+import { empty } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Controller.extend({
+export default Controller.extend({
/**
Is the "send test email" button disabled?
@property sendTestEmailDisabled
**/
- sendTestEmailDisabled: Ember.computed.empty("testEmailAddress"),
+ sendTestEmailDisabled: empty("testEmailAddress"),
/**
Clears the 'sentTestEmail' property on successful send.
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 c7c2df8c95..49a84ea6d1 100644
--- a/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-email-logs.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import EmailLog from "admin/models/email-log";
-export default Ember.Controller.extend({
+export default Controller.extend({
loading: false,
loadLogs(sourceModel, loadMore) {
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 407478d681..66b393196a 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,14 +1,16 @@
+import { empty, or, notEmpty } from "@ember/object/computed";
+import Controller from "@ember/controller";
import EmailPreview from "admin/models/email-preview";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default 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: empty("email"),
+ sendEmailDisabled: or("emailEmpty", "sendingEmail"),
+ showSendEmailForm: notEmpty("model.html_content"),
+ htmlEmpty: empty("model.html_content"),
actions: {
refresh() {
diff --git a/app/assets/javascripts/admin/controllers/admin-embedding.js.es6 b/app/assets/javascripts/admin/controllers/admin-embedding.js.es6
index a8b522130c..7e185e9d12 100644
--- a/app/assets/javascripts/admin/controllers/admin-embedding.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-embedding.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
saved: false,
embedding: null,
diff --git a/app/assets/javascripts/admin/controllers/admin-emojis.js.es6 b/app/assets/javascripts/admin/controllers/admin-emojis.js.es6
index d110904338..6a1d295759 100644
--- a/app/assets/javascripts/admin/controllers/admin-emojis.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-emojis.js.es6
@@ -1,6 +1,9 @@
+import { sort } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Controller.extend({
- sortedEmojis: Ember.computed.sort("model", "emojiSorting"),
+export default Controller.extend({
+ sortedEmojis: sort("model", "emojiSorting"),
init() {
this._super(...arguments);
@@ -11,7 +14,7 @@ export default Ember.Controller.extend({
actions: {
emojiUploaded(emoji) {
emoji.url += "?t=" + new Date().getTime();
- this.model.pushObject(Ember.Object.create(emoji));
+ this.model.pushObject(EmberObject.create(emoji));
},
destroy(emoji) {
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6
index 2a410f7705..5b0908c363 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-emails.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
import ScreenedEmail from "admin/models/screened-email";
-export default Ember.Controller.extend({
+export default Controller.extend({
loading: false,
actions: {
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
index 66ffe3c08c..2e404eb29d 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-ip-addresses.js.es6
@@ -1,9 +1,10 @@
+import Controller from "@ember/controller";
import debounce from "discourse/lib/debounce";
import { outputExportResult } from "discourse/lib/export-result";
import { exportEntity } from "discourse/lib/export-csv";
import ScreenedIpAddress from "admin/models/screened-ip-address";
-export default Ember.Controller.extend({
+export default Controller.extend({
loading: false,
filter: null,
savedIpAddress: null,
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6
index ef01562302..3f33783184 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-screened-urls.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
import ScreenedUrl from "admin/models/screened-url";
-export default Ember.Controller.extend({
+export default Controller.extend({
loading: false,
show() {
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
index a3d332c1f5..a375379fc0 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
@@ -1,3 +1,7 @@
+import { gt } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { scheduleOnce } from "@ember/runloop";
+import Controller from "@ember/controller";
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
import {
@@ -5,10 +9,10 @@ import {
on
} from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
model: null,
filters: null,
- filtersExists: Ember.computed.gt("filterCount", 0),
+ filtersExists: gt("filterCount", 0),
userHistoryActions: null,
@computed("filters.action_name")
@@ -19,14 +23,14 @@ export default Ember.Controller.extend({
@on("init")
resetFilters() {
this.setProperties({
- model: Ember.Object.create({ loadingMore: true }),
- filters: Ember.Object.create()
+ model: EmberObject.create({ loadingMore: true }),
+ filters: EmberObject.create()
});
this.scheduleRefresh();
},
_changeFilters(props) {
- this.set("model", Ember.Object.create({ loadingMore: true }));
+ this.set("model", EmberObject.create({ loadingMore: true }));
this.filters.setProperties(props);
this.scheduleRefresh();
},
@@ -66,7 +70,7 @@ export default Ember.Controller.extend({
},
scheduleRefresh() {
- Ember.run.scheduleOnce("afterRender", this, this._refresh);
+ scheduleOnce("afterRender", this, this._refresh);
},
actions: {
diff --git a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6 b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6
index 45e88514a0..d024c83051 100644
--- a/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-permalinks.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import debounce from "discourse/lib/debounce";
import Permalink from "admin/models/permalink";
-export default Ember.Controller.extend({
+export default Controller.extend({
loading: false,
filter: null,
diff --git a/app/assets/javascripts/admin/controllers/admin-plugins.js.es6 b/app/assets/javascripts/admin/controllers/admin-plugins.js.es6
index 36b1f7ca11..c0322317e5 100644
--- a/app/assets/javascripts/admin/controllers/admin-plugins.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-plugins.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
@computed
adminRoutes: function() {
return this.model
diff --git a/app/assets/javascripts/admin/controllers/admin-reports-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-reports-show.js.es6
index 2a78ece7f4..359be15f1d 100644
--- a/app/assets/javascripts/admin/controllers/admin-reports-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-reports-show.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
queryParams: ["start_date", "end_date", "filters"],
start_date: null,
end_date: null,
diff --git a/app/assets/javascripts/admin/controllers/admin-search-logs-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-search-logs-index.js.es6
index 5c26cb0e9f..397b4c9b9e 100644
--- a/app/assets/javascripts/admin/controllers/admin-search-logs-index.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-search-logs-index.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
export const DEFAULT_PERIOD = "yearly";
-export default Ember.Controller.extend({
+export default Controller.extend({
loading: false,
period: DEFAULT_PERIOD,
searchType: "all",
diff --git a/app/assets/javascripts/admin/controllers/admin-search-logs-term.js.es6 b/app/assets/javascripts/admin/controllers/admin-search-logs-term.js.es6
index 229aa67db8..66def62c97 100644
--- a/app/assets/javascripts/admin/controllers/admin-search-logs-term.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-search-logs-term.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import { DEFAULT_PERIOD } from "admin/controllers/admin-search-logs-index";
-export default Ember.Controller.extend({
+export default Controller.extend({
loading: false,
term: null,
period: DEFAULT_PERIOD,
diff --git a/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6
index a5831299ec..3fd10f15d1 100644
--- a/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-site-settings-category.js.es6
@@ -1,8 +1,10 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
categoryNameKey: null,
- adminSiteSettings: Ember.inject.controller(),
+ adminSiteSettings: inject(),
@computed("adminSiteSettings.visibleSiteSettings", "categoryNameKey")
category(categories, nameKey) {
diff --git a/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6
index 09a335946d..fe35885617 100644
--- a/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-site-settings.js.es6
@@ -1,14 +1,17 @@
+import { isEmpty } from "@ember/utils";
+import { alias } from "@ember/object/computed";
+import Controller from "@ember/controller";
import debounce from "discourse/lib/debounce";
-export default Ember.Controller.extend({
+export default Controller.extend({
filter: null,
- allSiteSettings: Ember.computed.alias("model"),
+ allSiteSettings: alias("model"),
visibleSiteSettings: null,
onlyOverridden: false,
filterContentNow(category) {
// If we have no content, don't bother filtering anything
- if (!!Ember.isEmpty(this.allSiteSettings)) return;
+ if (!!isEmpty(this.allSiteSettings)) return;
let filter;
if (this.filter) {
diff --git a/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6
index 4aa1c3d428..cd815b9ae8 100644
--- a/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-site-text-edit.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(bufferedProperty("siteText"), {
+export default Controller.extend(bufferedProperty("siteText"), {
saved: false,
@computed("buffered.value")
diff --git a/app/assets/javascripts/admin/controllers/admin-site-text-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-site-text-index.js.es6
index 1c484e4287..1a1b266ae1 100644
--- a/app/assets/javascripts/admin/controllers/admin-site-text-index.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-site-text-index.js.es6
@@ -1,6 +1,8 @@
+import { debounce } from "@ember/runloop";
+import Controller from "@ember/controller";
let lastSearch;
-export default Ember.Controller.extend({
+export default Controller.extend({
searching: false,
siteTexts: null,
preferred: false,
@@ -26,14 +28,14 @@ export default Ember.Controller.extend({
toggleOverridden() {
this.toggleProperty("overridden");
this.set("searching", true);
- Ember.run.debounce(this, this._performSearch, 400);
+ debounce(this, this._performSearch, 400);
},
search() {
const q = this.q;
if (q !== lastSearch) {
this.set("searching", true);
- Ember.run.debounce(this, this._performSearch, 400);
+ debounce(this, this._performSearch, 400);
lastSearch = q;
}
}
diff --git a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6
index d419cf9e34..fac3436c6e 100644
--- a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6
@@ -1,13 +1,17 @@
+import { alias, sort } from "@ember/object/computed";
+import { next } from "@ember/runloop";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import GrantBadgeController from "discourse/mixins/grant-badge-controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(GrantBadgeController, {
- adminUser: Ember.inject.controller(),
- user: Ember.computed.alias("adminUser.model"),
- userBadges: Ember.computed.alias("model"),
- allBadges: Ember.computed.alias("badges"),
- sortedBadges: Ember.computed.sort("model", "badgeSortOrder"),
+export default Controller.extend(GrantBadgeController, {
+ adminUser: inject(),
+ user: alias("adminUser.model"),
+ userBadges: alias("model"),
+ allBadges: alias("badges"),
+ sortedBadges: sort("model", "badgeSortOrder"),
init() {
this._super(...arguments);
@@ -69,7 +73,7 @@ export default Ember.Controller.extend(GrantBadgeController, {
).then(
() => {
this.set("badgeReason", "");
- Ember.run.next(() => {
+ next(() => {
// Update the selected badge ID after the combobox has re-rendered.
const newSelectedBadge = this.grantableBadges[0];
if (newSelectedBadge) {
diff --git a/app/assets/javascripts/admin/controllers/admin-user-fields.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-fields.js.es6
index 7d2a6b3d56..b81b08f559 100644
--- a/app/assets/javascripts/admin/controllers/admin-user-fields.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-user-fields.js.es6
@@ -1,11 +1,13 @@
+import { gte, sort } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
const MAX_FIELDS = 20;
-export default Ember.Controller.extend({
+export default Controller.extend({
fieldTypes: null,
- createDisabled: Ember.computed.gte("model.length", MAX_FIELDS),
- sortedFields: Ember.computed.sort("model", "fieldSortOrder"),
+ createDisabled: gte("model.length", MAX_FIELDS),
+ sortedFields: sort("model", "fieldSortOrder"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6
index 4a24bbd4b5..de2e37668f 100644
--- a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6
@@ -1,3 +1,6 @@
+import { notEmpty, and } from "@ember/object/computed";
+import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import CanCheckEmails from "discourse/mixins/can-check-emails";
import { propertyNotEqual, setting } from "discourse/lib/computed";
@@ -5,25 +8,24 @@ import { userPath } from "discourse/lib/url";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { fmt } from "discourse/lib/computed";
+import { htmlSafe } from "@ember/template";
-export default Ember.Controller.extend(CanCheckEmails, {
- adminTools: Ember.inject.service(),
+export default Controller.extend(CanCheckEmails, {
+ adminTools: service(),
originalPrimaryGroupId: null,
customGroupIdsBuffer: null,
availableGroups: null,
userTitleValue: null,
showBadges: setting("enable_badges"),
- hasLockedTrustLevel: Ember.computed.notEmpty(
- "model.manual_locked_trust_level"
- ),
+ hasLockedTrustLevel: notEmpty("model.manual_locked_trust_level"),
primaryGroupDirty: propertyNotEqual(
"originalPrimaryGroupId",
"model.primary_group_id"
),
- canDisableSecondFactor: Ember.computed.and(
+ canDisableSecondFactor: and(
"model.second_factor_enabled",
"model.can_disable_second_factor"
),
@@ -46,7 +48,7 @@ export default Ember.Controller.extend(CanCheckEmails, {
automaticGroups(automaticGroups) {
return automaticGroups
.map(group => {
- const name = Ember.String.htmlSafe(group.name);
+ const name = htmlSafe(group.name);
return `${name} `;
})
.join(", ");
@@ -257,10 +259,6 @@ export default Ember.Controller.extend(CanCheckEmails, {
.finally(() => this.toggleProperty("editingTitle"));
},
- generateApiKey() {
- this.model.generateApiKey();
- },
-
saveCustomGroups() {
const currentIds = this.customGroupIds;
const bufferedIds = this.customGroupIdsBuffer;
@@ -293,32 +291,6 @@ export default Ember.Controller.extend(CanCheckEmails, {
resetPrimaryGroup() {
this.set("model.primary_group_id", this.originalPrimaryGroupId);
- },
-
- regenerateApiKey() {
- bootbox.confirm(
- I18n.t("admin.api.confirm_regen"),
- I18n.t("no_value"),
- I18n.t("yes_value"),
- result => {
- if (result) {
- this.model.generateApiKey();
- }
- }
- );
- },
-
- revokeApiKey() {
- bootbox.confirm(
- I18n.t("admin.api.confirm_revoke"),
- I18n.t("no_value"),
- I18n.t("yes_value"),
- result => {
- if (result) {
- this.model.revokeApiKey();
- }
- }
- );
}
}
});
diff --git a/app/assets/javascripts/admin/controllers/admin-user.js.es6 b/app/assets/javascripts/admin/controllers/admin-user.js.es6
index 77c79b724a..cf6c4e3aa2 100644
--- a/app/assets/javascripts/admin/controllers/admin-user.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-user.js.es6
@@ -1 +1,2 @@
-export default Ember.Controller.extend();
+import Controller from "@ember/controller";
+export default Controller.extend();
diff --git a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
index 743e68d24b..944b0d9485 100644
--- a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
@@ -1,10 +1,11 @@
+import Controller from "@ember/controller";
import debounce from "discourse/lib/debounce";
import { i18n } from "discourse/lib/computed";
import AdminUser from "admin/models/admin-user";
import CanCheckEmails from "discourse/mixins/can-check-emails";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(CanCheckEmails, {
+export default Controller.extend(CanCheckEmails, {
model: null,
query: null,
order: null,
diff --git a/app/assets/javascripts/admin/controllers/admin-watched-words-action.js.es6 b/app/assets/javascripts/admin/controllers/admin-watched-words-action.js.es6
index cf4a28e2d3..1726446d8c 100644
--- a/app/assets/javascripts/admin/controllers/admin-watched-words-action.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-watched-words-action.js.es6
@@ -1,13 +1,17 @@
+import { or } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import WatchedWord from "admin/models/watched-word";
import { ajax } from "discourse/lib/ajax";
import { fmt } from "discourse/lib/computed";
import showModal from "discourse/lib/show-modal";
-export default Ember.Controller.extend({
+export default Controller.extend({
actionNameKey: null,
- adminWatchedWords: Ember.inject.controller(),
- showWordsList: Ember.computed.or(
+ adminWatchedWords: inject(),
+ showWordsList: or(
"adminWatchedWords.filtered",
"adminWatchedWords.showWords"
),
@@ -49,7 +53,7 @@ export default Ember.Controller.extend({
if (a) {
a.words.unshiftObject(arg);
a.incrementProperty("count");
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
// remove from other actions lists
let match = null;
this.get("adminWatchedWords.model").forEach(action => {
diff --git a/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6 b/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6
index 20ed611781..397c5b030e 100644
--- a/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-watched-words.js.es6
@@ -1,14 +1,18 @@
+import { isEmpty } from "@ember/utils";
+import { alias } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
import debounce from "discourse/lib/debounce";
-export default Ember.Controller.extend({
+export default Controller.extend({
filter: null,
filtered: false,
showWords: false,
- disableShowWords: Ember.computed.alias("filtered"),
+ disableShowWords: alias("filtered"),
regularExpressions: null,
filterContentNow() {
- if (!!Ember.isEmpty(this.allWatchedWords)) return;
+ if (!!isEmpty(this.allWatchedWords)) return;
let filter;
if (this.filter) {
@@ -27,7 +31,7 @@ export default Ember.Controller.extend({
return wordRecord.word.indexOf(filter) > -1;
});
matchesByAction.pushObject(
- Ember.Object.create({
+ EmberObject.create({
nameKey: wordsForAction.nameKey,
name: wordsForAction.name,
words: wordRecords,
@@ -41,7 +45,7 @@ export default Ember.Controller.extend({
filterContent: debounce(function() {
this.filterContentNow();
- this.set("filtered", !Ember.isEmpty(this.filter));
+ this.set("filtered", !isEmpty(this.filter));
}, 250).observes("filter"),
actions: {
diff --git a/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6 b/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6
index 388fab304f..e550a79069 100644
--- a/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6
@@ -1,10 +1,12 @@
+import { alias } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
pingDisabled: false,
- incomingCount: Ember.computed.alias("incomingEventIds.length"),
+ incomingCount: alias("incomingEventIds.length"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/admin/controllers/admin-web-hooks-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-web-hooks-show.js.es6
index 2a637d7278..83de79e1f0 100644
--- a/app/assets/javascripts/admin/controllers/admin-web-hooks-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-web-hooks-show.js.es6
@@ -1,13 +1,17 @@
+import { isEmpty } from "@ember/utils";
+import { alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { extractDomainFromUrl } from "discourse/lib/utilities";
import computed from "ember-addons/ember-computed-decorators";
import InputValidation from "discourse/models/input-validation";
-export default Ember.Controller.extend({
- adminWebHooks: Ember.inject.controller(),
- eventTypes: Ember.computed.alias("adminWebHooks.eventTypes"),
- defaultEventTypes: Ember.computed.alias("adminWebHooks.defaultEventTypes"),
- contentTypes: Ember.computed.alias("adminWebHooks.contentTypes"),
+export default Controller.extend({
+ adminWebHooks: inject(),
+ eventTypes: alias("adminWebHooks.eventTypes"),
+ defaultEventTypes: alias("adminWebHooks.defaultEventTypes"),
+ contentTypes: alias("adminWebHooks.contentTypes"),
@computed
showTagsFilter() {
@@ -35,7 +39,7 @@ export default Ember.Controller.extend({
@computed("model.secret")
secretValidation(secret) {
- if (!Ember.isEmpty(secret)) {
+ if (!isEmpty(secret)) {
if (secret.indexOf(" ") !== -1) {
return InputValidation.create({
failed: true,
@@ -54,7 +58,7 @@ export default Ember.Controller.extend({
@computed("model.wildcard_web_hook", "model.web_hook_event_types.[]")
eventTypeValidation(isWildcard, eventTypes) {
- if (!isWildcard && Ember.isEmpty(eventTypes)) {
+ if (!isWildcard && isEmpty(eventTypes)) {
return InputValidation.create({
failed: true,
reason: I18n.t("admin.web_hooks.event_type_missing")
@@ -76,7 +80,7 @@ export default Ember.Controller.extend({
) {
return isSaving
? false
- : secretValidation || eventTypeValidation || Ember.isEmpty(payloadUrl);
+ : secretValidation || eventTypeValidation || isEmpty(payloadUrl);
},
actions: {
diff --git a/app/assets/javascripts/admin/controllers/admin-web-hooks.js.es6 b/app/assets/javascripts/admin/controllers/admin-web-hooks.js.es6
index 696541c1cf..f9f401e330 100644
--- a/app/assets/javascripts/admin/controllers/admin-web-hooks.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-web-hooks.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
actions: {
destroy(webhook) {
return bootbox.confirm(
diff --git a/app/assets/javascripts/admin/controllers/admin.js.es6 b/app/assets/javascripts/admin/controllers/admin.js.es6
index a79cf81944..f01a898b0c 100644
--- a/app/assets/javascripts/admin/controllers/admin.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin.js.es6
@@ -1,7 +1,10 @@
+import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
+import { dasherize } from "@ember/string";
-export default Ember.Controller.extend({
- router: Ember.inject.service(),
+export default Controller.extend({
+ router: service(),
@computed("siteSettings.enable_group_directory")
showGroups(enableGroupDirectory) {
@@ -25,7 +28,7 @@ export default Ember.Controller.extend({
segment !== "admin"
);
})
- .map(Ember.String.dasherize)
+ .map(dasherize)
.join(" ");
// this is done to avoid breaking css customizations
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-add-upload.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-add-upload.js.es6
index 73f1f1e11f..d53278c856 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-add-upload.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-add-upload.js.es6
@@ -1,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import { and, not } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
import {
@@ -52,8 +56,8 @@ const SCSS_VARIABLE_NAMES = [
"love-low"
];
-export default Ember.Controller.extend(ModalFunctionality, {
- adminCustomizeThemesShow: Ember.inject.controller(),
+export default Controller.extend(ModalFunctionality, {
+ adminCustomizeThemesShow: inject(),
uploadUrl: "/admin/themes/upload_asset",
@@ -62,8 +66,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.set("fileSelected", false);
},
- enabled: Ember.computed.and("nameValid", "fileSelected"),
- disabled: Ember.computed.not("enabled"),
+ enabled: and("nameValid", "fileSelected"),
+ disabled: not("enabled"),
@computed("name", "adminCustomizeThemesShow.model.theme_fields")
errorMessage(name, themeFields) {
@@ -104,7 +108,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
actions: {
updateName() {
let name = this.name;
- if (Ember.isEmpty(name)) {
+ if (isEmpty(name)) {
name = $("#file-input")[0].files[0].name;
this.set("name", name.split(".")[0]);
}
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6
index 045a96c2aa..b6419c8e04 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js.es6
@@ -1,10 +1,12 @@
+import { alias, map } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { escapeExpression } from "discourse/lib/utilities";
-export default Ember.Controller.extend({
- sample: Ember.computed.alias("model.sample"),
- errors: Ember.computed.alias("model.errors"),
- count: Ember.computed.alias("model.grant_count"),
+export default Controller.extend({
+ sample: alias("model.sample"),
+ errors: alias("model.errors"),
+ count: alias("model.grant_count"),
@computed("count", "sample.length")
countWarning(count, sampleLength) {
@@ -33,7 +35,7 @@ export default Ember.Controller.extend({
return output;
},
- processedSample: Ember.computed.map("model.sample", grant => {
+ processedSample: map("model.sample", grant => {
let i18nKey = "admin.badges.preview.grant.with";
const i18nParams = { username: escapeExpression(grant.username) };
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-color-scheme-select-base.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-color-scheme-select-base.js.es6
index 374b6392f4..ea64338a83 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-color-scheme-select-base.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-color-scheme-select-base.js.es6
@@ -1,7 +1,9 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
- adminCustomizeColors: Ember.inject.controller(),
+export default Controller.extend(ModalFunctionality, {
+ adminCustomizeColors: inject(),
actions: {
selectBase() {
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6
index 76dc4c07d7..4d0c66143c 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-edit-badge-groupings.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { observes } from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
@observes("model")
modelChanged() {
const model = this.model;
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-incoming-email.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-incoming-email.js.es6
index e19afcd359..210d664cda 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-incoming-email.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-incoming-email.js.es6
@@ -1,10 +1,11 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import IncomingEmail from "admin/models/incoming-email";
import computed from "ember-addons/ember-computed-decorators";
import { longDate } from "discourse/lib/formatter";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
@computed("model.date")
date(d) {
return longDate(d);
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-install-theme.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-install-theme.js.es6
index a81e8caef7..81055d733d 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-install-theme.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-install-theme.js.es6
@@ -1,3 +1,6 @@
+import { equal, match, alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
@@ -7,28 +10,29 @@ import {
} from "ember-addons/ember-computed-decorators";
import { THEMES, COMPONENTS } from "admin/models/theme";
import { POPULAR_THEMES } from "discourse-common/helpers/popular-themes";
+import { set } from "@ember/object";
const MIN_NAME_LENGTH = 4;
-export default Ember.Controller.extend(ModalFunctionality, {
- popular: Ember.computed.equal("selection", "popular"),
- local: Ember.computed.equal("selection", "local"),
- remote: Ember.computed.equal("selection", "remote"),
- create: Ember.computed.equal("selection", "create"),
+export default Controller.extend(ModalFunctionality, {
+ popular: equal("selection", "popular"),
+ local: equal("selection", "local"),
+ remote: equal("selection", "remote"),
+ create: equal("selection", "create"),
selection: "popular",
- adminCustomizeThemes: Ember.inject.controller(),
+ adminCustomizeThemes: inject(),
loading: false,
keyGenUrl: "/admin/themes/generate_key_pair",
importUrl: "/admin/themes/import",
recordType: "theme",
- checkPrivate: Ember.computed.match("uploadUrl", /^git/),
+ checkPrivate: match("uploadUrl", /^git/),
localFile: null,
uploadUrl: null,
urlPlaceholder: "https://github.com/discourse/sample_theme",
advancedVisible: false,
- themesController: Ember.inject.controller("adminCustomizeThemes"),
- selectedType: Ember.computed.alias("themesController.currentTab"),
- component: Ember.computed.equal("selectedType", COMPONENTS),
+ themesController: inject("adminCustomizeThemes"),
+ selectedType: alias("themesController.currentTab"),
+ component: equal("selectedType", COMPONENTS),
init() {
this._super(...arguments);
@@ -43,7 +47,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
themes(installedThemes) {
return POPULAR_THEMES.map(t => {
if (installedThemes.includes(t.name)) {
- Ember.set(t, "installed", true);
+ set(t, "installed", true);
}
return t;
});
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-reseed.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-reseed.js.es6
index f71c7eaf2e..176c46be36 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-reseed.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-reseed.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: true,
reseeding: false,
categories: null,
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-silence-user.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-silence-user.js.es6
index 79ec3e6945..5c04066941 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-silence-user.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-silence-user.js.es6
@@ -1,7 +1,9 @@
+import { isEmpty } from "@ember/utils";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import PenaltyController from "admin/mixins/penalty-controller";
-export default Ember.Controller.extend(PenaltyController, {
+export default Controller.extend(PenaltyController, {
silenceUntil: null,
silencing: false,
@@ -12,9 +14,7 @@ export default Ember.Controller.extend(PenaltyController, {
@computed("silenceUntil", "reason", "silencing")
submitDisabled(silenceUntil, reason, silencing) {
- return (
- silencing || Ember.isEmpty(silenceUntil) || !reason || reason.length < 1
- );
+ return silencing || isEmpty(silenceUntil) || !reason || reason.length < 1;
},
actions: {
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6
index 23420631f0..06110e0113 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-staff-action-log-details.js.es6
@@ -1,3 +1,4 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality);
+export default Controller.extend(ModalFunctionality);
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6
index 7bd96b326a..b4cc2f188d 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-start-backup.js.es6
@@ -1,7 +1,9 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
- adminBackupsLogs: Ember.inject.controller(),
+export default Controller.extend(ModalFunctionality, {
+ adminBackupsLogs: inject(),
actions: {
startBackupWithUploads() {
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6
index c5911322c5..c5afea9d88 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-suspend-user.js.es6
@@ -1,7 +1,9 @@
+import { isEmpty } from "@ember/utils";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import PenaltyController from "admin/mixins/penalty-controller";
-export default Ember.Controller.extend(PenaltyController, {
+export default Controller.extend(PenaltyController, {
suspendUntil: null,
suspending: false,
@@ -12,9 +14,7 @@ export default Ember.Controller.extend(PenaltyController, {
@computed("suspendUntil", "reason", "suspending")
submitDisabled(suspendUntil, reason, suspending) {
- return (
- suspending || Ember.isEmpty(suspendUntil) || !reason || reason.length < 1
- );
+ return suspending || isEmpty(suspendUntil) || !reason || reason.length < 1;
},
actions: {
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-theme-change.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-theme-change.js.es6
index 834376a2d6..e33284d233 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-theme-change.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-theme-change.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loadDiff() {
this.set("loading", true);
ajax(
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-uploaded-image-list.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-uploaded-image-list.js.es6
index 22aa327651..a5ac891c21 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-uploaded-image-list.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-uploaded-image-list.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import { on, observes } from "ember-addons/ember-computed-decorators";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
@on("init")
@observes("model.value")
_setup() {
diff --git a/app/assets/javascripts/admin/controllers/modals/admin-watched-word-test.js.es6 b/app/assets/javascripts/admin/controllers/modals/admin-watched-word-test.js.es6
index 7af6650ca6..10f90ee615 100644
--- a/app/assets/javascripts/admin/controllers/modals/admin-watched-word-test.js.es6
+++ b/app/assets/javascripts/admin/controllers/modals/admin-watched-word-test.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
@computed("value", "model.compiledRegularExpression")
matches(value, regexpString) {
if (!value || !regexpString) return;
diff --git a/app/assets/javascripts/admin/controllers/modals/site-setting-default-categories.js.es6 b/app/assets/javascripts/admin/controllers/modals/site-setting-default-categories.js.es6
new file mode 100644
index 0000000000..62e77ed8e6
--- /dev/null
+++ b/app/assets/javascripts/admin/controllers/modals/site-setting-default-categories.js.es6
@@ -0,0 +1,20 @@
+import Controller from "@ember/controller";
+import ModalFunctionality from "discourse/mixins/modal-functionality";
+
+export default Controller.extend(ModalFunctionality, {
+ onShow() {
+ this.set("updateExistingUsers", null);
+ },
+
+ actions: {
+ updateExistingUsers() {
+ this.set("updateExistingUsers", true);
+ this.send("closeModal");
+ },
+
+ cancel() {
+ this.set("updateExistingUsers", false);
+ this.send("closeModal");
+ }
+ }
+});
diff --git a/app/assets/javascripts/admin/helpers/disposition-icon.js.es6 b/app/assets/javascripts/admin/helpers/disposition-icon.js.es6
index 2a2440a294..0e1ea29a27 100644
--- a/app/assets/javascripts/admin/helpers/disposition-icon.js.es6
+++ b/app/assets/javascripts/admin/helpers/disposition-icon.js.es6
@@ -1,6 +1,7 @@
import { iconHTML } from "discourse-common/lib/icon-library";
+import Helper from "@ember/component/helper";
-export default Ember.Helper.extend({
+export default Helper.extend({
compute([disposition]) {
if (!disposition) {
return null;
diff --git a/app/assets/javascripts/admin/helpers/post-action-title.js.es6 b/app/assets/javascripts/admin/helpers/post-action-title.js.es6
index 5ce437bf4a..657aee2e9b 100644
--- a/app/assets/javascripts/admin/helpers/post-action-title.js.es6
+++ b/app/assets/javascripts/admin/helpers/post-action-title.js.es6
@@ -1,3 +1,5 @@
+import Helper from "@ember/component/helper";
+
function postActionTitle([id, nameKey]) {
let title = I18n.t(`admin.flags.short_names.${nameKey}`, {
defaultValue: null
@@ -11,4 +13,4 @@ function postActionTitle([id, nameKey]) {
return title;
}
-export default Ember.Helper.helper(postActionTitle);
+export default Helper.helper(postActionTitle);
diff --git a/app/assets/javascripts/admin/mixins/penalty-controller.js.es6 b/app/assets/javascripts/admin/mixins/penalty-controller.js.es6
index b38e249da3..cb07e9d2ca 100644
--- a/app/assets/javascripts/admin/mixins/penalty-controller.js.es6
+++ b/app/assets/javascripts/admin/mixins/penalty-controller.js.es6
@@ -1,7 +1,9 @@
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { popupAjaxError } from "discourse/lib/ajax-error";
+import Mixin from "@ember/object/mixin";
+import { Promise } from "rsvp";
-export default Ember.Mixin.create(ModalFunctionality, {
+export default Mixin.create(ModalFunctionality, {
reason: null,
message: null,
postEdit: null,
@@ -25,7 +27,7 @@ export default Ember.Mixin.create(ModalFunctionality, {
penalize(cb) {
let before = this.before;
- let promise = before ? before() : Ember.RSVP.resolve();
+ let promise = before ? before() : Promise.resolve();
return promise
.then(() => cb())
diff --git a/app/assets/javascripts/admin/mixins/period-computation.js.es6 b/app/assets/javascripts/admin/mixins/period-computation.js.es6
index 4323532e84..354fd0ad85 100644
--- a/app/assets/javascripts/admin/mixins/period-computation.js.es6
+++ b/app/assets/javascripts/admin/mixins/period-computation.js.es6
@@ -1,7 +1,8 @@
import DiscourseURL from "discourse/lib/url";
import computed from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
queryParams: ["period"],
period: "monthly",
diff --git a/app/assets/javascripts/admin/mixins/setting-component.js.es6 b/app/assets/javascripts/admin/mixins/setting-component.js.es6
index 18be48a2d1..762d5cfa2b 100644
--- a/app/assets/javascripts/admin/mixins/setting-component.js.es6
+++ b/app/assets/javascripts/admin/mixins/setting-component.js.es6
@@ -1,5 +1,11 @@
+import { alias, oneWay } from "@ember/object/computed";
import computed from "ember-addons/ember-computed-decorators";
import { categoryLinkHTML } from "discourse/helpers/category-link";
+import { on } from "@ember/object/evented";
+import Mixin from "@ember/object/mixin";
+import showModal from "discourse/lib/show-modal";
+import AboutRoute from "discourse/routes/about";
+import { Promise } from "rsvp";
const CUSTOM_TYPES = [
"bool",
@@ -14,16 +20,17 @@ const CUSTOM_TYPES = [
"compact_list",
"secret_list",
"upload",
- "group_list"
+ "group_list",
+ "tag_list"
];
const AUTO_REFRESH_ON_SAVE = ["logo", "logo_small", "large_icon"];
-export default Ember.Mixin.create({
+export default Mixin.create({
classNameBindings: [":row", ":setting", "overridden", "typeClass"],
- content: Ember.computed.alias("setting"),
+ content: alias("setting"),
validationMessage: null,
- isSecret: Ember.computed.oneWay("setting.secret"),
+ isSecret: oneWay("setting.secret"),
@computed("buffered.value", "setting.value")
dirty(bufferVal, settingVal) {
@@ -89,33 +96,88 @@ export default Ember.Mixin.create({
return settingDefault !== bufferedValue;
},
- _watchEnterKey: function() {
+ _watchEnterKey: on("didInsertElement", function() {
$(this.element).on("keydown.setting-enter", ".input-setting-string", e => {
if (e.keyCode === 13) {
// enter key
this.send("save");
}
});
- }.on("didInsertElement"),
+ }),
- _removeBindings: function() {
+ _removeBindings: on("willDestroyElement", function() {
$(this.element).off("keydown.setting-enter");
- }.on("willDestroyElement"),
+ }),
_save() {
Ember.warn("You should define a `_save` method", {
id: "discourse.setting-component.missing-save"
});
- return Ember.RSVP.resolve();
+ return Promise.resolve();
},
actions: {
+ update() {
+ const defaultUserPreferences = [
+ "default_email_digest_frequency",
+ "default_include_tl0_in_digests",
+ "default_email_level",
+ "default_email_messages_level",
+ "default_email_mailing_list_mode",
+ "default_email_mailing_list_mode_frequency",
+ "disable_mailing_list_mode",
+ "default_email_previous_replies",
+ "default_email_in_reply_to",
+ "default_other_new_topic_duration_minutes",
+ "default_other_auto_track_topics_after_msecs",
+ "default_other_notification_level_when_replying",
+ "default_other_external_links_in_new_tab",
+ "default_other_enable_quoting",
+ "default_other_enable_defer",
+ "default_other_dynamic_favicon",
+ "default_other_like_notification_frequency",
+ "default_topics_automatic_unpin",
+ "default_categories_watching",
+ "default_categories_tracking",
+ "default_categories_muted",
+ "default_categories_watching_first_post",
+ "default_tags_watching",
+ "default_tags_tracking",
+ "default_tags_muted",
+ "default_tags_watching_first_post",
+ "default_text_size",
+ "default_title_count_mode"
+ ];
+ const key = this.buffered.get("setting");
+
+ if (defaultUserPreferences.includes(key)) {
+ AboutRoute.create()
+ .model()
+ .then(result => {
+ const controller = showModal("site-setting-default-categories", {
+ model: {
+ count: result.stats.user_count,
+ key: key.replace(/_/g, " ")
+ },
+ admin: true
+ });
+
+ controller.set("onClose", () => {
+ this.updateExistingUsers = controller.updateExistingUsers;
+ this.send("save");
+ });
+ });
+ } else {
+ this.send("save");
+ }
+ },
+
save() {
this._save()
.then(() => {
this.set("validationMessage", null);
this.commitBuffer();
- if (AUTO_REFRESH_ON_SAVE.includes(this.get("setting.setting"))) {
+ if (AUTO_REFRESH_ON_SAVE.includes(this.setting.setting)) {
this.afterSave();
}
})
diff --git a/app/assets/javascripts/admin/mixins/setting-object.js.es6 b/app/assets/javascripts/admin/mixins/setting-object.js.es6
index ef047af732..c02004cea8 100644
--- a/app/assets/javascripts/admin/mixins/setting-object.js.es6
+++ b/app/assets/javascripts/admin/mixins/setting-object.js.es6
@@ -1,6 +1,7 @@
import computed from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
@computed("value", "default")
overridden(val, defaultVal) {
if (val === null) val = "";
diff --git a/app/assets/javascripts/admin/models/admin-user.js.es6 b/app/assets/javascripts/admin/models/admin-user.js.es6
index 8a8ba62481..880cb44c39 100644
--- a/app/assets/javascripts/admin/models/admin-user.js.es6
+++ b/app/assets/javascripts/admin/models/admin-user.js.es6
@@ -1,26 +1,21 @@
+import { filter, or, gt, lt, not } from "@ember/object/computed";
import { iconHTML } from "discourse-common/lib/icon-library";
import { ajax } from "discourse/lib/ajax";
import computed from "ember-addons/ember-computed-decorators";
import { propertyNotEqual } from "discourse/lib/computed";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import ApiKey from "admin/models/api-key";
import Group from "discourse/models/group";
import { userPath } from "discourse/lib/url";
+import { Promise } from "rsvp";
const wrapAdmin = user => (user ? AdminUser.create(user) : null);
const AdminUser = Discourse.User.extend({
adminUserView: true,
- customGroups: Ember.computed.filter(
- "groups",
- g => !g.automatic && Group.create(g)
- ),
- automaticGroups: Ember.computed.filter(
- "groups",
- g => g.automatic && Group.create(g)
- ),
+ customGroups: filter("groups", g => !g.automatic && Group.create(g)),
+ automaticGroups: filter("groups", g => g.automatic && Group.create(g)),
- canViewProfile: Ember.computed.or("active", "staged"),
+ canViewProfile: or("active", "staged"),
@computed("bounce_score", "reset_bounce_score_after")
bounceScore(bounce_score, reset_bounce_score_after) {
@@ -49,7 +44,7 @@ const AdminUser = Discourse.User.extend({
return Discourse.getURL("/admin/email/bounced");
},
- canResetBounceScore: Ember.computed.gt("bounce_score", 0),
+ canResetBounceScore: gt("bounce_score", 0),
resetBounceScore() {
return ajax(`/admin/users/${this.id}/reset_bounce_score`, {
@@ -62,16 +57,6 @@ const AdminUser = Discourse.User.extend({
);
},
- generateApiKey() {
- return ajax(`/admin/users/${this.id}/generate_api_key`, {
- type: "POST"
- }).then(result => {
- const apiKey = ApiKey.create(result.api_key);
- this.set("api_key", apiKey);
- return apiKey;
- });
- },
-
groupAdded(added) {
return ajax(`/admin/users/${this.id}/groups`, {
type: "POST",
@@ -289,9 +274,9 @@ const AdminUser = Discourse.User.extend({
});
},
- canLockTrustLevel: Ember.computed.lt("trust_level", 4),
+ canLockTrustLevel: lt("trust_level", 4),
- canSuspend: Ember.computed.not("staff"),
+ canSuspend: not("staff"),
@computed("suspended_till", "suspended_at")
suspendDuration(suspendedTill, suspendedAt) {
@@ -519,7 +504,7 @@ const AdminUser = Discourse.User.extend({
loadDetails() {
if (this.loadedDetails) {
- return Ember.RSVP.resolve(this);
+ return Promise.resolve(this);
}
return AdminUser.find(this.id).then(result => {
@@ -557,9 +542,9 @@ AdminUser.reopenClass({
});
},
- findAll(query, filter) {
+ findAll(query, userFilter) {
return ajax(`/admin/users/list/${query}.json`, {
- data: filter
+ data: userFilter
}).then(users => users.map(u => AdminUser.create(u)));
}
});
diff --git a/app/assets/javascripts/admin/models/api-key.js.es6 b/app/assets/javascripts/admin/models/api-key.js.es6
index 62a4e003bf..95d8e1914c 100644
--- a/app/assets/javascripts/admin/models/api-key.js.es6
+++ b/app/assets/javascripts/admin/models/api-key.js.es6
@@ -1,47 +1,55 @@
import AdminUser from "admin/models/admin-user";
+import RestModel from "discourse/models/rest";
import { ajax } from "discourse/lib/ajax";
+import computed from "ember-addons/ember-computed-decorators";
-const KEY_ENDPOINT = "/admin/api/key";
-const KEYS_ENDPOINT = "/admin/api/keys";
+const ApiKey = RestModel.extend({
+ user: Ember.computed("_user", {
+ get() {
+ return this._user;
+ },
+ set(key, value) {
+ if (value && !(value instanceof AdminUser)) {
+ this.set("_user", AdminUser.create(value));
+ } else {
+ this.set("_user", value);
+ }
+ return this._user;
+ }
+ }),
-const ApiKey = Discourse.Model.extend({
- regenerate() {
- return ajax(KEY_ENDPOINT, {
- type: "PUT",
- data: { id: this.id }
- }).then(result => {
- this.set("key", result.api_key.key);
- return this;
- });
+ @computed("key")
+ shortKey(key) {
+ return `${key.substring(0, 4)}...`;
+ },
+
+ @computed("description")
+ shortDescription(description) {
+ if (!description || description.length < 40) return description;
+ return `${description.substring(0, 40)}...`;
},
revoke() {
- return ajax(KEY_ENDPOINT, {
- type: "DELETE",
- data: { id: this.id }
- });
- }
-});
-
-ApiKey.reopenClass({
- create() {
- const result = this._super.apply(this, arguments);
- if (result.user) {
- result.user = AdminUser.create(result.user);
- }
- return result;
+ return ajax(`${this.basePath}/revoke`, {
+ type: "POST"
+ }).then(result => this.setProperties(result.api_key));
},
- find() {
- return ajax(KEYS_ENDPOINT).then(keys =>
- keys.map(key => ApiKey.create(key))
- );
+ undoRevoke() {
+ return ajax(`${this.basePath}/undo-revoke`, {
+ type: "POST"
+ }).then(result => this.setProperties(result.api_key));
},
- generateMasterKey() {
- return ajax(KEY_ENDPOINT, { type: "POST" }).then(result =>
- ApiKey.create(result.api_key)
- );
+ createProperties() {
+ return this.getProperties("description", "username");
+ },
+
+ @computed()
+ basePath() {
+ return this.store
+ .adapterFor("api-key")
+ .pathFor(this.store, "api-key", this.id);
}
});
diff --git a/app/assets/javascripts/admin/models/backup-status.js.es6 b/app/assets/javascripts/admin/models/backup-status.js.es6
index 2eb856c3be..b7deec1c10 100644
--- a/app/assets/javascripts/admin/models/backup-status.js.es6
+++ b/app/assets/javascripts/admin/models/backup-status.js.es6
@@ -1,7 +1,8 @@
+import { not } from "@ember/object/computed";
import computed from "ember-addons/ember-computed-decorators";
export default Discourse.Model.extend({
- restoreDisabled: Ember.computed.not("restoreEnabled"),
+ restoreDisabled: not("restoreEnabled"),
@computed("allowRestore", "isOperationRunning")
restoreEnabled(allowRestore, isOperationRunning) {
diff --git a/app/assets/javascripts/admin/models/color-scheme.js.es6 b/app/assets/javascripts/admin/models/color-scheme.js.es6
index 26c8ccdc0e..8875bf2e5e 100644
--- a/app/assets/javascripts/admin/models/color-scheme.js.es6
+++ b/app/assets/javascripts/admin/models/color-scheme.js.es6
@@ -1,3 +1,4 @@
+import { not } from "@ember/object/computed";
import { ajax } from "discourse/lib/ajax";
import ColorSchemeColor from "admin/models/color-scheme-color";
import computed from "ember-addons/ember-computed-decorators";
@@ -59,7 +60,7 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, {
return !changed || this.saving || this.colors.any(c => !c.get("valid"));
},
- newRecord: Ember.computed.not("id"),
+ newRecord: not("id"),
save(opts) {
if (this.is_base || this.disableSave) return;
diff --git a/app/assets/javascripts/admin/models/report.js.es6 b/app/assets/javascripts/admin/models/report.js.es6
index c7967cc6d5..37c495e06f 100644
--- a/app/assets/javascripts/admin/models/report.js.es6
+++ b/app/assets/javascripts/admin/models/report.js.es6
@@ -1,3 +1,6 @@
+import { makeArray } from "discourse-common/lib/helpers";
+import { isEmpty } from "@ember/utils";
+import EmberObject from "@ember/object";
import { escapeExpression } from "discourse/lib/utilities";
import { ajax } from "discourse/lib/ajax";
import round from "discourse/lib/round";
@@ -135,7 +138,7 @@ const Report = Discourse.Model.extend({
@computed("data", "currentTotal")
currentAverage(data, total) {
- return Ember.makeArray(data).length === 0
+ return makeArray(data).length === 0
? 0
: parseFloat((total / parseFloat(data.length)).toFixed(1));
},
@@ -323,7 +326,7 @@ const Report = Discourse.Model.extend({
const formatedValue = () => {
const userId = row[properties.id];
- const user = Ember.Object.create({
+ const user = EmberObject.create({
username,
name: formatUsername(username),
avatar_template: row[properties.avatar]
@@ -391,7 +394,7 @@ const Report = Discourse.Model.extend({
},
_numberLabel(value, options = {}) {
- const formatNumbers = Ember.isEmpty(options.formatNumbers)
+ const formatNumbers = isEmpty(options.formatNumbers)
? true
: options.formatNumbers;
diff --git a/app/assets/javascripts/admin/models/screened-ip-address.js.es6 b/app/assets/javascripts/admin/models/screened-ip-address.js.es6
index c7f3863738..0449a666f3 100644
--- a/app/assets/javascripts/admin/models/screened-ip-address.js.es6
+++ b/app/assets/javascripts/admin/models/screened-ip-address.js.es6
@@ -1,3 +1,4 @@
+import { equal } from "@ember/object/computed";
import { ajax } from "discourse/lib/ajax";
import computed from "ember-addons/ember-computed-decorators";
@@ -7,7 +8,7 @@ const ScreenedIpAddress = Discourse.Model.extend({
return I18n.t(`admin.logs.screened_ips.actions.${actionName}`);
},
- isBlocked: Ember.computed.equal("action_name", "block"),
+ isBlocked: equal("action_name", "block"),
@computed("ip_address")
isRange(ipAddress) {
diff --git a/app/assets/javascripts/admin/models/site-setting.js.es6 b/app/assets/javascripts/admin/models/site-setting.js.es6
index ca1c175864..7760a61114 100644
--- a/app/assets/javascripts/admin/models/site-setting.js.es6
+++ b/app/assets/javascripts/admin/models/site-setting.js.es6
@@ -25,9 +25,14 @@ SiteSetting.reopenClass({
});
},
- update(key, value) {
+ update(key, value, opts = {}) {
const data = {};
data[key] = value;
+
+ if (opts["updateExistingUsers"] === true) {
+ data["updateExistingUsers"] = true;
+ }
+
return ajax(`/admin/site_settings/${key}`, { type: "PUT", data });
}
});
diff --git a/app/assets/javascripts/admin/models/theme.js.es6 b/app/assets/javascripts/admin/models/theme.js.es6
index 7e49ff9b9e..4ea3d3e216 100644
--- a/app/assets/javascripts/admin/models/theme.js.es6
+++ b/app/assets/javascripts/admin/models/theme.js.es6
@@ -1,3 +1,6 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
+import { or, gt } from "@ember/object/computed";
import RestModel from "discourse/models/rest";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
@@ -13,9 +16,9 @@ export const COMPONENTS = "components";
const SETTINGS_TYPE_ID = 5;
const Theme = RestModel.extend({
- isActive: Ember.computed.or("default", "user_selectable"),
- isPendingUpdates: Ember.computed.gt("remote_theme.commits_behind", 0),
- hasEditedFields: Ember.computed.gt("editedFields.length", 0),
+ isActive: or("default", "user_selectable"),
+ isPendingUpdates: gt("remote_theme.commits_behind", 0),
+ hasEditedFields: gt("editedFields.length", 0),
@computed("theme_fields.[]")
targets() {
@@ -160,11 +163,11 @@ const Theme = RestModel.extend({
hasEdited(target, name) {
if (name) {
- return !Ember.isEmpty(this.getField(target, name));
+ return !isEmpty(this.getField(target, name));
} else {
let fields = this.theme_fields || [];
return fields.any(
- field => field.target === target && !Ember.isEmpty(field.value)
+ field => field.target === target && !isEmpty(field.value)
);
}
},
@@ -226,8 +229,8 @@ const Theme = RestModel.extend({
themeFields[key] = field;
} else {
const changed =
- (Ember.isEmpty(existingField.value) && !Ember.isEmpty(value)) ||
- (Ember.isEmpty(value) && !Ember.isEmpty(existingField.value));
+ (isEmpty(existingField.value) && !isEmpty(value)) ||
+ (isEmpty(value) && !isEmpty(existingField.value));
existingField.value = value;
if (changed) {
@@ -241,7 +244,7 @@ const Theme = RestModel.extend({
@computed("childThemes.[]")
child_theme_ids(childThemes) {
if (childThemes) {
- return childThemes.map(theme => Ember.get(theme, "id"));
+ return childThemes.map(theme => get(theme, "id"));
}
},
diff --git a/app/assets/javascripts/admin/models/user-field.js.es6 b/app/assets/javascripts/admin/models/user-field.js.es6
index a57e452d86..78c004d418 100644
--- a/app/assets/javascripts/admin/models/user-field.js.es6
+++ b/app/assets/javascripts/admin/models/user-field.js.es6
@@ -1,9 +1,10 @@
+import EmberObject from "@ember/object";
import RestModel from "discourse/models/rest";
import { i18n } from "discourse/lib/computed";
const UserField = RestModel.extend();
-const UserFieldType = Ember.Object.extend({
+const UserFieldType = EmberObject.extend({
name: i18n("id", "admin.user_fields.field_types.%@")
});
diff --git a/app/assets/javascripts/admin/models/version-check.js.es6 b/app/assets/javascripts/admin/models/version-check.js.es6
index ce41d66713..2012d0ff08 100644
--- a/app/assets/javascripts/admin/models/version-check.js.es6
+++ b/app/assets/javascripts/admin/models/version-check.js.es6
@@ -17,12 +17,10 @@ const VersionCheck = Discourse.Model.extend({
return missingVersionsCount === 1;
},
- @computed("git_branch", "installed_sha")
- gitLink(gitBranch, installedSHA) {
- if (gitBranch && installedSHA) {
- return `https://github.com/discourse/discourse/compare/${installedSHA}...${gitBranch}`;
- } else if (installedSHA) {
- return `https://github.com/discourse/discourse/tree/${installedSHA}`;
+ @computed("installed_sha")
+ gitLink(installedSHA) {
+ if (installedSHA) {
+ return `https://github.com/discourse/discourse/commits/${installedSHA}`;
}
},
diff --git a/app/assets/javascripts/admin/models/watched-word.js.es6 b/app/assets/javascripts/admin/models/watched-word.js.es6
index 9f335032e3..b9ef7380b6 100644
--- a/app/assets/javascripts/admin/models/watched-word.js.es6
+++ b/app/assets/javascripts/admin/models/watched-word.js.es6
@@ -1,4 +1,5 @@
import { ajax } from "discourse/lib/ajax";
+import EmberObject from "@ember/object";
const WatchedWord = Discourse.Model.extend({
save() {
@@ -37,7 +38,7 @@ WatchedWord.reopenClass({
});
return Object.keys(actions).map(n => {
- return Ember.Object.create({
+ return EmberObject.create({
nameKey: n,
name: I18n.t("admin.watched_words.actions." + n),
words: actions[n],
diff --git a/app/assets/javascripts/admin/models/web-hook.js.es6 b/app/assets/javascripts/admin/models/web-hook.js.es6
index cc35f47437..84111591fa 100644
--- a/app/assets/javascripts/admin/models/web-hook.js.es6
+++ b/app/assets/javascripts/admin/models/web-hook.js.es6
@@ -1,3 +1,4 @@
+import { isEmpty } from "@ember/utils";
import RestModel from "discourse/models/rest";
import Category from "discourse/models/category";
import Group from "discourse/models/group";
@@ -78,13 +79,13 @@ export default RestModel.extend({
wildcard_web_hook: this.wildcard_web_hook,
verify_certificate: this.verify_certificate,
active: this.active,
- web_hook_event_type_ids: Ember.isEmpty(types)
+ web_hook_event_type_ids: isEmpty(types)
? [null]
: types.map(type => type.id),
- category_ids: Ember.isEmpty(categoryIds) ? [null] : categoryIds,
- tag_names: Ember.isEmpty(tagNames) ? [null] : tagNames,
+ category_ids: isEmpty(categoryIds) ? [null] : categoryIds,
+ tag_names: isEmpty(tagNames) ? [null] : tagNames,
group_ids:
- Ember.isEmpty(groupNames) || Ember.isEmpty(groupNames[0])
+ isEmpty(groupNames) || isEmpty(groupNames[0])
? [null]
: Discourse.Site.currentProp("groups").reduce((groupIds, g) => {
if (groupNames.includes(g.name)) {
diff --git a/app/assets/javascripts/admin/routes/admin-api-index.js.es6 b/app/assets/javascripts/admin/routes/admin-api-index.js.es6
index c66efab129..f770f90c91 100644
--- a/app/assets/javascripts/admin/routes/admin-api-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-api-index.js.es6
@@ -1,4 +1,6 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+
+export default Route.extend({
beforeModel() {
this.transitionTo("adminApiKeys");
}
diff --git a/app/assets/javascripts/admin/routes/admin-api-keys-index.js.es6 b/app/assets/javascripts/admin/routes/admin-api-keys-index.js.es6
new file mode 100644
index 0000000000..25f6df3e4a
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-api-keys-index.js.es6
@@ -0,0 +1,7 @@
+import Route from "@ember/routing/route";
+
+export default Route.extend({
+ model() {
+ return this.store.findAll("api-key");
+ }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-api-keys-new.es6 b/app/assets/javascripts/admin/routes/admin-api-keys-new.es6
new file mode 100644
index 0000000000..3969615c9f
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-api-keys-new.es6
@@ -0,0 +1,7 @@
+import Route from "@ember/routing/route";
+
+export default Route.extend({
+ model() {
+ return this.store.createRecord("api-key");
+ }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-api-keys-show.js.es6 b/app/assets/javascripts/admin/routes/admin-api-keys-show.js.es6
new file mode 100644
index 0000000000..b21f2cd021
--- /dev/null
+++ b/app/assets/javascripts/admin/routes/admin-api-keys-show.js.es6
@@ -0,0 +1,5 @@
+export default Ember.Route.extend({
+ model(params) {
+ return this.store.find("api-key", params.api_key_id);
+ }
+});
diff --git a/app/assets/javascripts/admin/routes/admin-api-keys.js.es6 b/app/assets/javascripts/admin/routes/admin-api-keys.js.es6
index 4332cb0adc..1b3f3067fc 100644
--- a/app/assets/javascripts/admin/routes/admin-api-keys.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-api-keys.js.es6
@@ -1,7 +1,13 @@
-import ApiKey from "admin/models/api-key";
+import Route from "@ember/routing/route";
-export default Ember.Route.extend({
- model() {
- return ApiKey.find();
+export default Route.extend({
+ actions: {
+ show(apiKey) {
+ this.transitionTo("adminApiKeys.show", apiKey.id);
+ },
+
+ new() {
+ this.transitionTo("adminApiKeys.new");
+ }
}
});
diff --git a/app/assets/javascripts/admin/routes/admin-backups-index.js.es6 b/app/assets/javascripts/admin/routes/admin-backups-index.js.es6
index 39ed982a78..d20da4ac50 100644
--- a/app/assets/javascripts/admin/routes/admin-backups-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-backups-index.js.es6
@@ -1,6 +1,7 @@
+import Route from "@ember/routing/route";
import Backup from "admin/models/backup";
-export default Ember.Route.extend({
+export default Route.extend({
activate() {
this.messageBus.subscribe("/admin/backups", backups =>
this.controller.set("model", backups.map(backup => Backup.create(backup)))
diff --git a/app/assets/javascripts/admin/routes/admin-backups-logs.js.es6 b/app/assets/javascripts/admin/routes/admin-backups-logs.js.es6
index a0febc3d1d..3d24756a4a 100644
--- a/app/assets/javascripts/admin/routes/admin-backups-logs.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-backups-logs.js.es6
@@ -1,6 +1,8 @@
+import EmberObject from "@ember/object";
+import Route from "@ember/routing/route";
import PreloadStore from "preload-store";
-export default Ember.Route.extend({
+export default Route.extend({
// since the logs are pushed via the message bus
// we only want to preload them (hence the beforeModel hook)
beforeModel() {
@@ -15,7 +17,7 @@ export default Ember.Route.extend({
return log.message.length === 0 || log.message[0] === "[";
})
.map(function(log) {
- return Ember.Object.create(log);
+ return EmberObject.create(log);
})
.value();
logs.pushObjects(newLogs);
diff --git a/app/assets/javascripts/admin/routes/admin-backups.js.es6 b/app/assets/javascripts/admin/routes/admin-backups.js.es6
index b70c978286..5025f41536 100644
--- a/app/assets/javascripts/admin/routes/admin-backups.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-backups.js.es6
@@ -1,3 +1,5 @@
+import EmberObject from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import showModal from "discourse/lib/show-modal";
import BackupStatus from "admin/models/backup-status";
@@ -6,7 +8,7 @@ import PreloadStore from "preload-store";
const LOG_CHANNEL = "/admin/backups/logs";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
activate() {
this.messageBus.subscribe(LOG_CHANNEL, log => {
if (log.message === "[STARTED]") {
@@ -41,7 +43,7 @@ export default Discourse.Route.extend({
} else {
this.controllerFor("adminBackupsLogs")
.get("logs")
- .pushObject(Ember.Object.create(log));
+ .pushObject(EmberObject.create(log));
}
});
},
diff --git a/app/assets/javascripts/admin/routes/admin-badges-index.js.es6 b/app/assets/javascripts/admin/routes/admin-badges-index.js.es6
index 84a5bee571..36a4414877 100644
--- a/app/assets/javascripts/admin/routes/admin-badges-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-badges-index.js.es6
@@ -1,3 +1,4 @@
+import Route from "@ember/routing/route";
import { emojiUrlFor } from "discourse/lib/text";
const badgeIntroLinks = [
@@ -13,7 +14,7 @@ const badgeIntroLinks = [
}
];
-export default Ember.Route.extend({
+export default Route.extend({
setupController(controller) {
controller.setProperties({
badgeIntroLinks,
diff --git a/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 b/app/assets/javascripts/admin/routes/admin-badges-show.js.es6
index 7837d1b30d..36043f6096 100644
--- a/app/assets/javascripts/admin/routes/admin-badges-show.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-badges-show.js.es6
@@ -1,10 +1,12 @@
+import { get } from "@ember/object";
+import Route from "@ember/routing/route";
import { ajax } from "discourse/lib/ajax";
import Badge from "discourse/models/badge";
import showModal from "discourse/lib/show-modal";
-export default Ember.Route.extend({
+export default Route.extend({
serialize(m) {
- return { badge_id: Ember.get(m, "id") || "new" };
+ return { badge_id: get(m, "id") || "new" };
},
model(params) {
diff --git a/app/assets/javascripts/admin/routes/admin-badges.js.es6 b/app/assets/javascripts/admin/routes/admin-badges.js.es6
index 9fee47fb4e..0dac4bbaa2 100644
--- a/app/assets/javascripts/admin/routes/admin-badges.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-badges.js.es6
@@ -1,8 +1,9 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import Badge from "discourse/models/badge";
import BadgeGrouping from "discourse/models/badge-grouping";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
_json: null,
model() {
diff --git a/app/assets/javascripts/admin/routes/admin-customize-colors-show.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-colors-show.js.es6
index 545a09ad9b..146a3a61a9 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-colors-show.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-colors-show.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model(params) {
const all = this.modelFor("adminCustomize.colors");
const model = all.findBy("id", parseInt(params.scheme_id));
diff --git a/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6
index f4853fda28..835814df07 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-colors.js.es6
@@ -1,6 +1,7 @@
+import Route from "@ember/routing/route";
import ColorScheme from "admin/models/color-scheme";
-export default Ember.Route.extend({
+export default Route.extend({
model() {
return ColorScheme.findAll();
},
diff --git a/app/assets/javascripts/admin/routes/admin-customize-email-style-edit.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-email-style-edit.js.es6
index 74649c1a00..8dcc18f0d9 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-email-style-edit.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-email-style-edit.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model(params) {
return {
model: this.modelFor("adminCustomizeEmailStyle"),
diff --git a/app/assets/javascripts/admin/routes/admin-customize-email-style.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-email-style.js.es6
index 8e202e62bd..d63186e0eb 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-email-style.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-email-style.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model() {
return this.store.find("email-style");
},
diff --git a/app/assets/javascripts/admin/routes/admin-customize-email-templates-edit.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-email-templates-edit.js.es6
index a6f170b09e..0bf85baf4a 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-email-templates-edit.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-email-templates-edit.js.es6
@@ -1,6 +1,7 @@
+import Route from "@ember/routing/route";
import { scrollTop } from "discourse/mixins/scroll-top";
-export default Ember.Route.extend({
+export default Route.extend({
model(params) {
const all = this.modelFor("adminCustomizeEmailTemplates");
return all.findBy("id", params.id);
diff --git a/app/assets/javascripts/admin/routes/admin-customize-email-templates.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-email-templates.js.es6
index fa6d3041a6..39b04b835f 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-email-templates.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-email-templates.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model() {
return this.store.findAll("email-template");
},
diff --git a/app/assets/javascripts/admin/routes/admin-customize-index.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-index.js.es6
index 10d55df015..9c593b7e25 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-index.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
beforeModel() {
this.transitionTo("adminCustomizeThemes");
}
diff --git a/app/assets/javascripts/admin/routes/admin-customize-robots-txt.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-robots-txt.js.es6
index 50acd6cac1..866d7cf8ec 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-robots-txt.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-robots-txt.js.es6
@@ -1,6 +1,7 @@
+import Route from "@ember/routing/route";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Route.extend({
+export default Route.extend({
model() {
return ajax("/admin/customize/robots");
}
diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6
index 2e37bdc1ce..335e9fd578 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-themes-edit.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model(params) {
const all = this.modelFor("adminCustomizeThemes");
const model = all.findBy("id", parseInt(params.theme_id));
diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6
index ea09122d62..425a04617a 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-themes-index.js.es6
@@ -1,3 +1,4 @@
+import Route from "@ember/routing/route";
import { emojiUrlFor } from "discourse/lib/text";
const externalResources = [
@@ -18,7 +19,7 @@ const externalResources = [
}
];
-export default Ember.Route.extend({
+export default Route.extend({
setupController(controller) {
this._super(...arguments);
this.controllerFor("adminCustomizeThemes").set("editingTheme", false);
diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6
index a0ca4feef8..c9573fd8ac 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-themes-show.js.es6
@@ -1,7 +1,8 @@
+import Route from "@ember/routing/route";
import { scrollTop } from "discourse/mixins/scroll-top";
import { THEMES, COMPONENTS } from "admin/models/theme";
-export default Ember.Route.extend({
+export default Route.extend({
serialize(model) {
return { theme_id: model.get("id") };
},
diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6
index 91c7ec5b76..7f7274ee0e 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6
@@ -1,6 +1,7 @@
+import Route from "@ember/routing/route";
import showModal from "discourse/lib/show-modal";
-export default Ember.Route.extend({
+export default Route.extend({
model() {
return this.store.findAll("theme");
},
diff --git a/app/assets/javascripts/admin/routes/admin-dashboard-general.js.es6 b/app/assets/javascripts/admin/routes/admin-dashboard-general.js.es6
index ffd544b3db..1ee1b22121 100644
--- a/app/assets/javascripts/admin/routes/admin-dashboard-general.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-dashboard-general.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
activate() {
this.controllerFor("admin-dashboard-general").fetchDashboard();
}
diff --git a/app/assets/javascripts/admin/routes/admin-dashboard-reports.js.es6 b/app/assets/javascripts/admin/routes/admin-dashboard-reports.js.es6
index 7aea901096..0de5bfe505 100644
--- a/app/assets/javascripts/admin/routes/admin-dashboard-reports.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-dashboard-reports.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return ajax("/admin/reports").then(json => json);
},
diff --git a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6 b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
index a6ff3c215e..905a148bc7 100644
--- a/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-dashboard.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { scrollTop } from "discourse/mixins/scroll-top";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
activate() {
this.controllerFor("admin-dashboard").fetchProblems();
this.controllerFor("admin-dashboard").fetchDashboard();
diff --git a/app/assets/javascripts/admin/routes/admin-email-incomings.js.es6 b/app/assets/javascripts/admin/routes/admin-email-incomings.js.es6
index 79331282bb..aa86f7f31d 100644
--- a/app/assets/javascripts/admin/routes/admin-email-incomings.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-email-incomings.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import IncomingEmail from "admin/models/incoming-email";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return IncomingEmail.findAll({ status: this.status });
},
diff --git a/app/assets/javascripts/admin/routes/admin-email-index.js.es6 b/app/assets/javascripts/admin/routes/admin-email-index.js.es6
index ca912cc009..878885f983 100644
--- a/app/assets/javascripts/admin/routes/admin-email-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-email-index.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import EmailSettings from "admin/models/email-settings";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return EmailSettings.find();
}
diff --git a/app/assets/javascripts/admin/routes/admin-email-logs.js.es6 b/app/assets/javascripts/admin/routes/admin-email-logs.js.es6
index 7813fb93fd..8ebfebd199 100644
--- a/app/assets/javascripts/admin/routes/admin-email-logs.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-email-logs.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
setupController(controller) {
controller.setProperties({
loading: true,
diff --git a/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6 b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6
index 972f3c9b6d..391ec6c75b 100644
--- a/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-email-preview-digest.js.es6
@@ -1,9 +1,10 @@
+import DiscourseRoute from "discourse/routes/discourse";
import {
default as EmailPreview,
oneWeekAgo
} from "admin/models/email-preview";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return EmailPreview.findDigest(this.currentUser.get("username"));
},
diff --git a/app/assets/javascripts/admin/routes/admin-embedding.js.es6 b/app/assets/javascripts/admin/routes/admin-embedding.js.es6
index d698c52450..080dce2083 100644
--- a/app/assets/javascripts/admin/routes/admin-embedding.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-embedding.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model() {
return this.store.find("embedding");
},
diff --git a/app/assets/javascripts/admin/routes/admin-emojis.js.es6 b/app/assets/javascripts/admin/routes/admin-emojis.js.es6
index f412a90898..dd7e94d40a 100644
--- a/app/assets/javascripts/admin/routes/admin-emojis.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-emojis.js.es6
@@ -1,9 +1,12 @@
+import EmberObject from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
-export default Discourse.Route.extend({
+
+export default DiscourseRoute.extend({
model: function() {
return ajax("/admin/customize/emojis.json").then(function(emojis) {
return emojis.map(function(emoji) {
- return Ember.Object.create(emoji);
+ return EmberObject.create(emoji);
});
});
}
diff --git a/app/assets/javascripts/admin/routes/admin-flags-posts-active.js.es6 b/app/assets/javascripts/admin/routes/admin-flags-posts-active.js.es6
index d971939503..1a1d01a091 100644
--- a/app/assets/javascripts/admin/routes/admin-flags-posts-active.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-flags-posts-active.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
return this.store.findAll("flagged-post", { filter: "active" });
}
diff --git a/app/assets/javascripts/admin/routes/admin-flags-posts-old.js.es6 b/app/assets/javascripts/admin/routes/admin-flags-posts-old.js.es6
index c7d22ccdad..a4157d5714 100644
--- a/app/assets/javascripts/admin/routes/admin-flags-posts-old.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-flags-posts-old.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
return this.store.findAll("flagged-post", { filter: "old" });
}
diff --git a/app/assets/javascripts/admin/routes/admin-flags-topics-index.js.es6 b/app/assets/javascripts/admin/routes/admin-flags-topics-index.js.es6
index d635328c05..5fb295d648 100644
--- a/app/assets/javascripts/admin/routes/admin-flags-topics-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-flags-topics-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
return this.store.findAll("flagged-topic");
},
diff --git a/app/assets/javascripts/admin/routes/admin-logs-index.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-index.js.es6
index ff4c94aada..d003b429b6 100644
--- a/app/assets/javascripts/admin/routes/admin-logs-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-logs-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
redirect: function() {
this.transitionTo("adminLogs.staffActionLogs");
}
diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6
index f4f3a4f673..2016a96188 100644
--- a/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-logs-screened-emails.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
renderTemplate: function() {
this.render("admin/templates/logs/screened-emails", { into: "adminLogs" });
},
diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6
index 24000436b7..4343785594 100644
--- a/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-logs-screened-ip-addresses.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
renderTemplate() {
this.render("admin/templates/logs/screened-ip-addresses", {
into: "adminLogs"
diff --git a/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6
index 2369a886cd..ba0b76c9c5 100644
--- a/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-logs-screened-urls.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
renderTemplate: function() {
this.render("admin/templates/logs/screened-urls", { into: "adminLogs" });
},
diff --git a/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6
index fd1fea9615..0ef8e6e232 100644
--- a/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import showModal from "discourse/lib/show-modal";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
// TODO: make this automatic using an `{{outlet}}`
renderTemplate: function() {
this.render("admin/templates/logs/staff-action-logs", {
diff --git a/app/assets/javascripts/admin/routes/admin-permalinks.js.es6 b/app/assets/javascripts/admin/routes/admin-permalinks.js.es6
index d8c3c43865..996b90aaa8 100644
--- a/app/assets/javascripts/admin/routes/admin-permalinks.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-permalinks.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Permalink from "admin/models/permalink";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return Permalink.findAll();
},
diff --git a/app/assets/javascripts/admin/routes/admin-plugins.js.es6 b/app/assets/javascripts/admin/routes/admin-plugins.js.es6
index 06ea7eb259..c4af286faf 100644
--- a/app/assets/javascripts/admin/routes/admin-plugins.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-plugins.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model() {
return this.store.findAll("plugin");
},
diff --git a/app/assets/javascripts/admin/routes/admin-reports-index.js.es6 b/app/assets/javascripts/admin/routes/admin-reports-index.js.es6
index 2d21467ae6..864f1a3fb2 100644
--- a/app/assets/javascripts/admin/routes/admin-reports-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-reports-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
beforeModel() {
this.transitionTo("admin.dashboardReports");
}
diff --git a/app/assets/javascripts/admin/routes/admin-reports-show.js.es6 b/app/assets/javascripts/admin/routes/admin-reports-show.js.es6
index 9bf9ff8eba..1fa8bc739d 100644
--- a/app/assets/javascripts/admin/routes/admin-reports-show.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-reports-show.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
queryParams: {
start_date: { refreshModel: true },
end_date: { refreshModel: true },
diff --git a/app/assets/javascripts/admin/routes/admin-route-map.js.es6 b/app/assets/javascripts/admin/routes/admin-route-map.js.es6
index 478a851d86..f90b66f97a 100644
--- a/app/assets/javascripts/admin/routes/admin-route-map.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-route-map.js.es6
@@ -101,7 +101,14 @@ export default function() {
);
this.route("adminApi", { path: "/api", resetNamespace: true }, function() {
- this.route("adminApiKeys", { path: "/keys", resetNamespace: true });
+ this.route(
+ "adminApiKeys",
+ { path: "/keys", resetNamespace: true },
+ function() {
+ this.route("show", { path: "/:api_key_id" });
+ this.route("new", { path: "/new" });
+ }
+ );
this.route(
"adminWebHooks",
diff --git a/app/assets/javascripts/admin/routes/admin-search-logs-index.js.es6 b/app/assets/javascripts/admin/routes/admin-search-logs-index.js.es6
index 966032045e..8244c0f2af 100644
--- a/app/assets/javascripts/admin/routes/admin-search-logs-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-search-logs-index.js.es6
@@ -1,6 +1,8 @@
+import EmberObject from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
queryParams: {
period: { refreshModel: true },
searchType: { refreshModel: true }
@@ -11,7 +13,7 @@ export default Discourse.Route.extend({
return ajax("/admin/logs/search_logs.json", {
data: { period: params.period, search_type: params.searchType }
}).then(search_logs => {
- return search_logs.map(sl => Ember.Object.create(sl));
+ return search_logs.map(sl => EmberObject.create(sl));
});
},
diff --git a/app/assets/javascripts/admin/routes/admin-search-logs-term.js.es6 b/app/assets/javascripts/admin/routes/admin-search-logs-term.js.es6
index 40d3e25be6..7c9c8f274c 100644
--- a/app/assets/javascripts/admin/routes/admin-search-logs-term.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-search-logs-term.js.es6
@@ -1,8 +1,10 @@
+import EmberObject from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { fillMissingDates } from "discourse/lib/utilities";
import { translateResults } from "discourse/lib/search";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
queryParams: {
term: { refreshModel: true },
period: { refreshModel: true },
@@ -32,7 +34,7 @@ export default Discourse.Route.extend({
json.term.search_result = translateResults(json.term.search_result);
}
- const model = Ember.Object.create({ type: "search_log_term" });
+ const model = EmberObject.create({ type: "search_log_term" });
model.setProperties(json.term);
return model;
});
diff --git a/app/assets/javascripts/admin/routes/admin-site-settings-category.js.es6 b/app/assets/javascripts/admin/routes/admin-site-settings-category.js.es6
index a774415083..b5a2f810b2 100644
--- a/app/assets/javascripts/admin/routes/admin-site-settings-category.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-site-settings-category.js.es6
@@ -1,4 +1,7 @@
-export default Discourse.Route.extend({
+import EmberObject from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model(params) {
// The model depends on user input, so let the controller do the work:
this.controllerFor("adminSiteSettingsCategory").set(
@@ -9,7 +12,7 @@ export default Discourse.Route.extend({
"categoryNameKey",
params.category_id
);
- return Ember.Object.create({
+ return EmberObject.create({
nameKey: params.category_id,
name: I18n.t("admin.site_settings.categories." + params.category_id),
siteSettings: this.controllerFor("adminSiteSettingsCategory").get(
diff --git a/app/assets/javascripts/admin/routes/admin-site-settings-index.js.es6 b/app/assets/javascripts/admin/routes/admin-site-settings-index.js.es6
index 59e851e509..88a091c4b9 100644
--- a/app/assets/javascripts/admin/routes/admin-site-settings-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-site-settings-index.js.es6
@@ -2,7 +2,9 @@
Handles when you click the Site Settings tab in admin, but haven't
chosen a category. It will redirect to the first category.
**/
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
beforeModel() {
this.replaceWith(
"adminSiteSettingsCategory",
diff --git a/app/assets/javascripts/admin/routes/admin-site-settings.js.es6 b/app/assets/javascripts/admin/routes/admin-site-settings.js.es6
index b6c3e857ea..ab687a4585 100644
--- a/app/assets/javascripts/admin/routes/admin-site-settings.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-site-settings.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import SiteSetting from "admin/models/site-setting";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
queryParams: {
filter: { replace: true }
},
diff --git a/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6 b/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6
index 00ccca0256..c423eae45a 100644
--- a/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-site-text-edit.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model(params) {
return this.store.find("site-text", params.id);
},
diff --git a/app/assets/javascripts/admin/routes/admin-site-text-index.js.es6 b/app/assets/javascripts/admin/routes/admin-site-text-index.js.es6
index dfec2f64d3..815dd1c084 100644
--- a/app/assets/javascripts/admin/routes/admin-site-text-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-site-text-index.js.es6
@@ -1,6 +1,8 @@
+import Route from "@ember/routing/route";
import showModal from "discourse/lib/show-modal";
+import { getProperties } from "@ember/object";
-export default Ember.Route.extend({
+export default Route.extend({
queryParams: {
q: { replace: true },
overridden: { replace: true }
@@ -9,7 +11,7 @@ export default Ember.Route.extend({
model(params) {
return this.store.find(
"site-text",
- Ember.getProperties(params, "q", "overridden")
+ getProperties(params, "q", "overridden")
);
},
diff --git a/app/assets/javascripts/admin/routes/admin-user-badges.js.es6 b/app/assets/javascripts/admin/routes/admin-user-badges.js.es6
index b585117f19..cce32753d1 100644
--- a/app/assets/javascripts/admin/routes/admin-user-badges.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-user-badges.js.es6
@@ -1,7 +1,8 @@
+import DiscourseRoute from "discourse/routes/discourse";
import UserBadge from "discourse/models/user-badge";
import Badge from "discourse/models/badge";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
const username = this.modelFor("adminUser").get("username");
return UserBadge.findByUsername(username);
diff --git a/app/assets/javascripts/admin/routes/admin-user-fields.js.es6 b/app/assets/javascripts/admin/routes/admin-user-fields.js.es6
index c4278dc627..ea4e0adef0 100644
--- a/app/assets/javascripts/admin/routes/admin-user-fields.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-user-fields.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import UserField from "admin/models/user-field";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model: function() {
return this.store.findAll("user-field");
},
diff --git a/app/assets/javascripts/admin/routes/admin-user-index.js.es6 b/app/assets/javascripts/admin/routes/admin-user-index.js.es6
index 2b623dbcf8..51af9f2d2e 100644
--- a/app/assets/javascripts/admin/routes/admin-user-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-user-index.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Group from "discourse/models/group";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return this.modelFor("adminUser");
},
diff --git a/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6 b/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6
index 6364e89f7c..17cd54dc8a 100644
--- a/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-user-tl3-requirements.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
return this.modelFor("adminUser");
}
diff --git a/app/assets/javascripts/admin/routes/admin-user.js.es6 b/app/assets/javascripts/admin/routes/admin-user.js.es6
index c25f750c25..563c63d0a5 100644
--- a/app/assets/javascripts/admin/routes/admin-user.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-user.js.es6
@@ -1,6 +1,8 @@
+import { get } from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
import AdminUser from "admin/models/admin-user";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
serialize(model) {
return {
user_id: model.get("id"),
@@ -9,7 +11,7 @@ export default Discourse.Route.extend({
},
model(params) {
- return AdminUser.find(Ember.get(params, "user_id"));
+ return AdminUser.find(get(params, "user_id"));
},
renderTemplate() {
diff --git a/app/assets/javascripts/admin/routes/admin-users-index.js.es6 b/app/assets/javascripts/admin/routes/admin-users-index.js.es6
index 8b28ea79fc..7549cb230c 100644
--- a/app/assets/javascripts/admin/routes/admin-users-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-users-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
redirect: function() {
this.transitionTo("adminUsersList");
}
diff --git a/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6
index 696345ad42..9f15d72cff 100644
--- a/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-users-list-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
beforeModel: function() {
this.transitionTo("adminUsersList.show", "active");
}
diff --git a/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6
index e0c1105566..764fe4ad34 100644
--- a/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-users-list-show.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
queryParams: {
order: { refreshModel: true },
ascending: { refreshModel: true }
diff --git a/app/assets/javascripts/admin/routes/admin-users-list.js.es6 b/app/assets/javascripts/admin/routes/admin-users-list.js.es6
index d6b76356f1..9e520d1735 100644
--- a/app/assets/javascripts/admin/routes/admin-users-list.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-users-list.js.es6
@@ -1,8 +1,9 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
import AdminUser from "admin/models/admin-user";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
actions: {
exportUsers() {
exportEntity("user_list", {
diff --git a/app/assets/javascripts/admin/routes/admin-watched-words-action.js.es6 b/app/assets/javascripts/admin/routes/admin-watched-words-action.js.es6
index 99450e09ce..358cfebe67 100644
--- a/app/assets/javascripts/admin/routes/admin-watched-words-action.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-watched-words-action.js.es6
@@ -1,4 +1,7 @@
-export default Discourse.Route.extend({
+import EmberObject from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model(params) {
this.controllerFor("adminWatchedWordsAction").set(
"actionNameKey",
@@ -7,7 +10,7 @@ export default Discourse.Route.extend({
let filteredContent = this.controllerFor("adminWatchedWordsAction").get(
"filteredContent"
);
- return Ember.Object.create({
+ return EmberObject.create({
nameKey: params.action_id,
name: I18n.t("admin.watched_words.actions." + params.action_id),
words: filteredContent
diff --git a/app/assets/javascripts/admin/routes/admin-watched-words-index.js.es6 b/app/assets/javascripts/admin/routes/admin-watched-words-index.js.es6
index 4ff2351e1b..a957c11478 100644
--- a/app/assets/javascripts/admin/routes/admin-watched-words-index.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-watched-words-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
beforeModel() {
this.replaceWith(
"adminWatchedWords.action",
diff --git a/app/assets/javascripts/admin/routes/admin-watched-words.js.es6 b/app/assets/javascripts/admin/routes/admin-watched-words.js.es6
index 8970e6a614..924ab49779 100644
--- a/app/assets/javascripts/admin/routes/admin-watched-words.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-watched-words.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import WatchedWord from "admin/models/watched-word";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
queryParams: {
filter: { replace: true }
},
diff --git a/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6 b/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6
index 1e0d3220cf..64f28d3652 100644
--- a/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6
@@ -1,9 +1,9 @@
-export default Discourse.Route.extend({
+import { get } from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model(params) {
- return this.store.findAll(
- "web-hook-event",
- Ember.get(params, "web_hook_id")
- );
+ return this.store.findAll("web-hook-event", get(params, "web_hook_id"));
},
setupController(controller, model) {
diff --git a/app/assets/javascripts/admin/routes/admin-web-hooks-show.js.es6 b/app/assets/javascripts/admin/routes/admin-web-hooks-show.js.es6
index 611b015dcb..34aed775cc 100644
--- a/app/assets/javascripts/admin/routes/admin-web-hooks-show.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-web-hooks-show.js.es6
@@ -1,4 +1,8 @@
-export default Discourse.Route.extend({
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
serialize(model) {
return { web_hook_id: model.get("id") || "new" };
},
@@ -7,14 +11,11 @@ export default Discourse.Route.extend({
if (params.web_hook_id === "new") {
return this.store.createRecord("web-hook");
}
- return this.store.find("web-hook", Ember.get(params, "web_hook_id"));
+ return this.store.find("web-hook", get(params, "web_hook_id"));
},
setupController(controller, model) {
- if (
- model.get("isNew") ||
- Ember.isEmpty(model.get("web_hook_event_types"))
- ) {
+ if (model.get("isNew") || isEmpty(model.get("web_hook_event_types"))) {
model.set("web_hook_event_types", controller.get("defaultEventTypes"));
}
diff --git a/app/assets/javascripts/admin/routes/admin-web-hooks.js.es6 b/app/assets/javascripts/admin/routes/admin-web-hooks.js.es6
index eed884a8ab..30daf6b6cb 100644
--- a/app/assets/javascripts/admin/routes/admin-web-hooks.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-web-hooks.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
model() {
return this.store.findAll("web-hook");
},
diff --git a/app/assets/javascripts/admin/routes/admin.js.es6 b/app/assets/javascripts/admin/routes/admin.js.es6
index fa373dd937..bc4e8173ef 100644
--- a/app/assets/javascripts/admin/routes/admin.js.es6
+++ b/app/assets/javascripts/admin/routes/admin.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("admin_title");
},
diff --git a/app/assets/javascripts/admin/services/admin-tools.js.es6 b/app/assets/javascripts/admin/services/admin-tools.js.es6
index 7f3b4d88a8..bb5e1ac06a 100644
--- a/app/assets/javascripts/admin/services/admin-tools.js.es6
+++ b/app/assets/javascripts/admin/services/admin-tools.js.es6
@@ -2,13 +2,16 @@
// and the admin application. Use this if you need front end code to access admin
// modules. Inject it optionally, and if it exists go to town!
+import EmberObject from "@ember/object";
import AdminUser from "admin/models/admin-user";
import { iconHTML } from "discourse-common/lib/icon-library";
import { ajax } from "discourse/lib/ajax";
import showModal from "discourse/lib/show-modal";
import { getOwner } from "discourse-common/lib/get-owner";
+import Service from "@ember/service";
+import { Promise } from "rsvp";
-export default Ember.Service.extend({
+export default Service.extend({
init() {
this._super(...arguments);
@@ -21,7 +24,7 @@ export default Ember.Service.extend({
"controller:adminLogs.staffActionLogs"
);
target.transitionToRoute("adminLogs.staffActionLogs").then(() => {
- controller.set("filters", Ember.Object.create());
+ controller.set("filters", EmberObject.create());
controller._changeFilters(filters);
});
},
@@ -52,7 +55,7 @@ export default Ember.Service.extend({
controller.setProperties({ postId: opts.postId, postEdit: opts.postEdit });
return (user.adminUserView
- ? Ember.RSVP.resolve(user)
+ ? Promise.resolve(user)
: AdminUser.find(user.get("id"))
).then(loadedUser => {
controller.setProperties({
@@ -76,7 +79,7 @@ export default Ember.Service.extend({
// Try loading the email if the site supports it
let tryEmail = this.siteSettings.moderators_view_emails
? adminUser.checkEmail()
- : Ember.RSVP.resolve();
+ : Promise.resolve();
return tryEmail.then(() => {
let message = I18n.messageFormat("flagging.delete_confirm_MF", {
@@ -90,7 +93,7 @@ export default Ember.Service.extend({
let userId = adminUser.get("id");
- return new Ember.RSVP.Promise((resolve, reject) => {
+ return new Promise((resolve, reject) => {
const buttons = [
{
label: I18n.t("composer.cancel"),
diff --git a/app/assets/javascripts/admin/templates/api-keys.hbs b/app/assets/javascripts/admin/templates/api-keys-index.hbs
similarity index 55%
rename from app/assets/javascripts/admin/templates/api-keys.hbs
rename to app/assets/javascripts/admin/templates/api-keys-index.hbs
index a1254f3042..a0d5bf9f77 100644
--- a/app/assets/javascripts/admin/templates/api-keys.hbs
+++ b/app/assets/javascripts/admin/templates/api-keys-index.hbs
@@ -1,7 +1,14 @@
+{{d-button
+ class="btn-primary"
+ action=(route-action "new")
+ icon="plus"
+ label="admin.api.new_key"}}
+
{{#if model}}
{{i18n "admin.api.key"}}
+ {{i18n "admin.api.description"}}
{{i18n "admin.api.user"}}
{{i18n "admin.api.created"}}
{{i18n "admin.api.last_used"}}
@@ -9,8 +16,14 @@
{{#each model as |k|}}
-
- {{k.key}}
+
+
+ {{#if k.revoked_at}}{{d-icon 'times-circle'}}{{/if}}
+ {{k.shortKey}}
+
+
+ {{k.shortDescription}}
+
{{i18n 'admin.api.user'}}
{{#if k.user}}
@@ -34,17 +47,21 @@
{{/if}}
- {{d-button
- class="btn-default"
- action=(action "regenerateKey")
- actionParam=k icon="undo"
- label="admin.api.regenerate"}}
- {{d-button
- class="btn-default"
- action=(action "revokeKey")
- actionParam=k
- icon="times"
- label="admin.api.revoke"}}
+ {{d-button action=(route-action "show" k) icon="far-eye" title="admin.api.show_details"}}
+ {{#if k.revoked_at}}
+ {{d-button
+ action=(action "undoRevokeKey")
+ actionParam=k icon="undo"
+ title="admin.api.undo_revoke"}}
+ {{else}}
+ {{d-button
+ class="btn-danger"
+ action=(action "revokeKey")
+ actionParam=k
+ icon="times"
+ title="admin.api.revoke"}}
+ {{/if}}
+
{{/each}}
@@ -52,11 +69,4 @@
{{else}}
{{i18n "admin.api.none"}}
-{{/if}}
-
-{{#unless hasMasterKey}}
- {{d-button
- class="btn-primary"
- action=(action "generateMasterKey")
- icon="key"}}
-{{/unless}}
+{{/if}}
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/templates/api-keys-new.hbs b/app/assets/javascripts/admin/templates/api-keys-new.hbs
new file mode 100644
index 0000000000..15f25b1ce1
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/api-keys-new.hbs
@@ -0,0 +1,27 @@
+{{#link-to 'adminApiKeys.index' class="go-back"}}
+ {{d-icon 'arrow-left'}}
+ {{i18n 'admin.api.all_api_keys'}}
+{{/link-to}}
+
+
+ {{#admin-form-row label="admin.api.description"}}
+ {{input value=model.description maxlength="255" placeholder=(i18n "admin.api.description_placeholder")}}
+ {{/admin-form-row}}
+
+ {{#admin-form-row label="admin.api.user_mode"}}
+ {{combo-box content=userModes value=userMode onSelect=(action "changeUserMode")}}
+ {{/admin-form-row}}
+
+ {{#if showUserSelector}}
+ {{#admin-form-row label="admin.api.user"}}
+ {{user-selector single="true"
+ usernames=model.username
+ placeholderKey="admin.api.user_placeholder"
+ }}
+ {{/admin-form-row}}
+ {{/if}}
+
+ {{#admin-form-row}}
+ {{d-button icon="check" label="admin.api.save" action=(action "save") class="btn-primary" disabled=saveDisabled}}
+ {{/admin-form-row}}
+
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/templates/api-keys-show.hbs b/app/assets/javascripts/admin/templates/api-keys-show.hbs
new file mode 100644
index 0000000000..a742cf994a
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/api-keys-show.hbs
@@ -0,0 +1,80 @@
+{{#link-to 'adminApiKeys.index' class="go-back"}}
+ {{d-icon 'arrow-left'}}
+ {{i18n 'admin.api.all_api_keys'}}
+{{/link-to}}
+
+
+ {{#admin-form-row label="admin.api.key"}}
+ {{#if model.revoked_at}}{{d-icon 'times-circle'}}{{/if}}
+ {{model.key}}
+ {{/admin-form-row}}
+
+ {{#admin-form-row label="admin.api.description"}}
+ {{#if editingDescription}}
+ {{input value=buffered.description maxlength="255" placeholder=(i18n "admin.api.description_placeholder")}}
+ {{else}}
+
{{if model.description model.description (i18n "admin.api.no_description")}}
+ {{/if}}
+
+
+ {{#if editingDescription}}
+ {{d-button class="ok" action=(action "saveDescription") icon="check"}}
+ {{d-button class="cancel" action=(action "editDescription") icon="times"}}
+ {{else}}
+ {{d-button class="btn-default" action=(action "editDescription") icon="pencil-alt"}}
+ {{/if}}
+
+ {{/admin-form-row}}
+
+ {{#admin-form-row label="admin.api.user"}}
+ {{#if model.user}}
+ {{#link-to "adminUser" model.user}}
+ {{avatar model.user imageSize="small"}} {{model.user.username}}
+ {{/link-to}}
+ {{else}}
+ {{i18n "admin.api.all_users"}}
+ {{/if}}
+ {{/admin-form-row}}
+
+ {{#admin-form-row label="admin.api.created"}}
+ {{format-date model.created_at leaveAgo="true"}}
+ {{/admin-form-row}}
+
+ {{#admin-form-row label="admin.api.updated"}}
+ {{format-date model.updated_at leaveAgo="true"}}
+ {{/admin-form-row}}
+
+ {{#admin-form-row label="admin.api.last_used"}}
+ {{#if k.last_used_at}}
+ {{format-date k.last_used_at leaveAgo="true"}}
+ {{else}}
+ {{i18n "admin.api.never_used"}}
+ {{/if}}
+ {{/admin-form-row}}
+
+ {{#admin-form-row label="admin.api.revoked"}}
+ {{#if model.revoked_at}}
+ {{format-date model.revoked_at leaveAgo="true"}}
+ {{/if}}
+
+ {{#if model.revoked_at}}
+ {{d-button
+ action=(action "undoRevokeKey")
+ actionParam=model icon="undo"
+ label="admin.api.undo_revoke"}}
+ {{d-button
+ action=(action "deleteKey")
+ actionParam=model icon="trash"
+ label="admin.api.delete"
+ class="btn-danger"}}
+ {{else}}
+ {{d-button
+ class="btn-danger"
+ action=(action "revokeKey")
+ actionParam=model
+ icon="times"
+ label="admin.api.revoke"}}
+ {{/if}}
+
+ {{/admin-form-row}}
+
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/templates/badges-show.hbs b/app/assets/javascripts/admin/templates/badges-show.hbs
index eaaa9fcde1..7a50b1084b 100644
--- a/app/assets/javascripts/admin/templates/badges-show.hbs
+++ b/app/assets/javascripts/admin/templates/badges-show.hbs
@@ -39,7 +39,10 @@
content=badgeGroupings
class="badge-selector"
nameProperty="name"}}
- {{d-icon "pencil-alt"}}
+ {{d-button
+ class="btn-default"
+ action=(route-action "editGroupings")
+ icon="pencil-alt"}}
@@ -138,7 +141,11 @@
-{{ace-editor content=editorContents mode=fieldName editorId=editorId}}
+{{ace-editor content=editorContents mode=currentEditorMode editorId=editorId}}
{{/if}}
- {{#d-button action=(action "editTheme") class="btn btn-default edit"}}{{i18n 'admin.customize.theme.edit_css_html'}}{{/d-button}}
+ {{d-button
+ class="btn-default edit"
+ action=(action "editTheme")
+ label="admin.customize.theme.edit_css_html"}}
diff --git a/app/assets/javascripts/admin/templates/email-advanced-test.hbs b/app/assets/javascripts/admin/templates/email-advanced-test.hbs
index c0b8ee7a27..34853b20e8 100644
--- a/app/assets/javascripts/admin/templates/email-advanced-test.hbs
+++ b/app/assets/javascripts/admin/templates/email-advanced-test.hbs
@@ -3,7 +3,9 @@
{{i18n 'admin.email.advanced_test.email'}}
{{textarea name="email" value=email class="email-body"}}
- {{i18n 'admin.email.advanced_test.run'}}
+ {{d-button
+ action=(action "run")
+ label="admin.email.advanced_test.run"}}
{{#conditional-loading-spinner condition=loading}}
diff --git a/app/assets/javascripts/admin/templates/email-index.hbs b/app/assets/javascripts/admin/templates/email-index.hbs
index c21e3a5ca6..42109ddaa9 100644
--- a/app/assets/javascripts/admin/templates/email-index.hbs
+++ b/app/assets/javascripts/admin/templates/email-index.hbs
@@ -20,7 +20,11 @@
{{text-field value=testEmailAddress placeholderKey="admin.email.test_email_address"}}
- {{i18n 'admin.email.send_test'}}
+ {{d-button
+ class="btn-primary"
+ action=(action "sendTestEmail")
+ disabled=sendTestEmailDisabled
+ label="admin.email.send_test"}}
{{#if sentTestEmailMessage}}{{sentTestEmailMessage}} {{/if}}
{{/if}}
diff --git a/app/assets/javascripts/admin/templates/email-preview-digest.hbs b/app/assets/javascripts/admin/templates/email-preview-digest.hbs
index 32df5b0d97..932aa9ffc2 100644
--- a/app/assets/javascripts/admin/templates/email-preview-digest.hbs
+++ b/app/assets/javascripts/admin/templates/email-preview-digest.hbs
@@ -6,7 +6,10 @@
{{date-picker-past value=lastSeen id="last-seen"}}
{{i18n 'admin.email.user'}}:
{{user-selector single="true" usernames=username canReceiveUpdates="true"}}
- {{i18n 'admin.email.refresh'}}
+ {{d-button
+ class="btn-primary digest-refresh-button"
+ action=(action "refresh")
+ label="admin.email.refresh"}}
{{i18n 'admin.email.format'}}
{{#if showHtml}}
@@ -30,7 +33,11 @@
{{else}}
{{i18n 'admin.email.send_digest_label'}}
{{text-field value=email placeholderKey="admin.email.test_email_address"}}
- {{i18n 'admin.email.send_digest'}}
+ {{d-button
+ class="btn-default"
+ action=(action "sendEmail")
+ disabled=sendEmailDisabled
+ label="admin.email.send_digest"}}
{{#if sentEmail}}
{{i18n 'admin.email.sent_test'}}
{{/if}}
@@ -51,4 +58,4 @@
-{{/conditional-loading-spinner}}
\ No newline at end of file
+{{/conditional-loading-spinner}}
diff --git a/app/assets/javascripts/admin/templates/emojis.hbs b/app/assets/javascripts/admin/templates/emojis.hbs
index f677287654..6281b15c05 100644
--- a/app/assets/javascripts/admin/templates/emojis.hbs
+++ b/app/assets/javascripts/admin/templates/emojis.hbs
@@ -20,7 +20,12 @@
:{{e.name}}:
- {{d-icon "far-trash-alt"}}
+
+ {{d-button
+ action=(action "destroy" e)
+ class="btn-danger pull-right"
+ icon="far-trash-alt"}}
+
{{/each}}
diff --git a/app/assets/javascripts/admin/templates/logs/screened-emails.hbs b/app/assets/javascripts/admin/templates/logs/screened-emails.hbs
index 532e68c29c..e8cb30140c 100644
--- a/app/assets/javascripts/admin/templates/logs/screened-emails.hbs
+++ b/app/assets/javascripts/admin/templates/logs/screened-emails.hbs
@@ -1,7 +1,13 @@
{{i18n 'admin.logs.screened_emails.description'}}
- {{d-icon "download"}}{{i18n 'admin.export_csv.button_text'}}
+
+{{d-button
+ class="btn-default screened-email-export"
+ action=(action "exportScreenedEmailList")
+ title="admin.export_csv.button_title.screened_email"
+ icon="download"
+ label="admin.export_csv.button_text"}}
diff --git a/app/assets/javascripts/admin/templates/logs/screened-urls.hbs b/app/assets/javascripts/admin/templates/logs/screened-urls.hbs
index c2a526e5f7..1ee4274368 100644
--- a/app/assets/javascripts/admin/templates/logs/screened-urls.hbs
+++ b/app/assets/javascripts/admin/templates/logs/screened-urls.hbs
@@ -1,7 +1,12 @@
{{i18n 'admin.logs.screened_urls.description'}}
- {{d-icon "download"}}{{i18n 'admin.export_csv.button_text'}}
+ {{d-button
+ class="btn-default"
+ action=(action "exportScreenedUrlList")
+ title="admin.export_csv.button_title.screened_url"
+ icon="download"
+ label="admin.export_csv.button_text"}}
{{#conditional-loading-spinner condition=loading}}
diff --git a/app/assets/javascripts/admin/templates/modal/admin-color-scheme-select-base.hbs b/app/assets/javascripts/admin/templates/modal/admin-color-scheme-select-base.hbs
index 371c06df49..e1978b918a 100644
--- a/app/assets/javascripts/admin/templates/modal/admin-color-scheme-select-base.hbs
+++ b/app/assets/javascripts/admin/templates/modal/admin-color-scheme-select-base.hbs
@@ -7,6 +7,10 @@
valueAttribute="base_scheme_id"}}
{{/d-modal-body}}
diff --git a/app/assets/javascripts/admin/templates/modal/admin-start-backup.hbs b/app/assets/javascripts/admin/templates/modal/admin-start-backup.hbs
index 0990760888..dd201e2aed 100644
--- a/app/assets/javascripts/admin/templates/modal/admin-start-backup.hbs
+++ b/app/assets/javascripts/admin/templates/modal/admin-start-backup.hbs
@@ -1,5 +1,12 @@
{{#d-modal-body title="admin.backups.operations.backup.confirm"}}
- {{i18n 'yes_value'}}
- {{i18n 'admin.backups.operations.backup.without_uploads'}}
- {{i18n 'no_value'}}
+ {{d-button
+ class="btn-primary"
+ action=(action "startBackupWithUploads")
+ label="yes_value"}}
+ {{d-button
+ action=(action "startBackupWithoutUploads")
+ label="admin.backups.operations.backup.without_uploads"}}
+ {{d-button
+ action=(action "cancel")
+ label="no_value"}}
{{/d-modal-body}}
diff --git a/app/assets/javascripts/admin/templates/modal/admin-theme-change.hbs b/app/assets/javascripts/admin/templates/modal/admin-theme-change.hbs
index 1b6b06870a..ec26f608d8 100644
--- a/app/assets/javascripts/admin/templates/modal/admin-theme-change.hbs
+++ b/app/assets/javascripts/admin/templates/modal/admin-theme-change.hbs
@@ -3,6 +3,9 @@
{{{diff}}}
{{/d-modal-body}}
diff --git a/app/assets/javascripts/admin/templates/modal/site-setting-default-categories.hbs b/app/assets/javascripts/admin/templates/modal/site-setting-default-categories.hbs
new file mode 100644
index 0000000000..0bd05c2ba8
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/modal/site-setting-default-categories.hbs
@@ -0,0 +1,8 @@
+{{#d-modal-body class="incoming-emails" rawTitle=model.key}}
+{{i18n "admin.site_settings.default_categories.modal_description" count=model.count}}
+{{/d-modal-body}}
+
+
diff --git a/app/assets/javascripts/admin/templates/user-badges.hbs b/app/assets/javascripts/admin/templates/user-badges.hbs
index 92e4403fe1..9f81cd2f74 100644
--- a/app/assets/javascripts/admin/templates/user-badges.hbs
+++ b/app/assets/javascripts/admin/templates/user-badges.hbs
@@ -22,7 +22,10 @@
{{i18n 'admin.badges.reason'}}
{{input type="text" value=badgeReason}}{{i18n 'admin.badges.reason_help'}}
- {{i18n 'admin.badges.grant'}}
+ {{d-button
+ class="btn-primary"
+ action=(action "grantBadge")
+ label="admin.badges.grant"}}
{{/if}}
@@ -52,9 +55,14 @@
{{age-with-tooltip userBadge.granted_at}}
{{#if userBadge.grouped}}
- {{{i18n 'admin.badges.expand'}}}
+ {{d-button
+ action=(action "expandGroup" userBadge)
+ label="admin.badges.expand"}}
{{else}}
- {{i18n 'admin.badges.revoke'}}
+ {{d-button
+ class="btn-danger"
+ action=(action "revokeBadge" userBadge)
+ label="admin.badges.revoke"}}
{{/if}}
diff --git a/app/assets/javascripts/admin/templates/user-index.hbs b/app/assets/javascripts/admin/templates/user-index.hbs
index 6166eb1b9a..7eb9504fb5 100644
--- a/app/assets/javascripts/admin/templates/user-index.hbs
+++ b/app/assets/javascripts/admin/templates/user-index.hbs
@@ -292,33 +292,14 @@
{{#if currentUser.admin}}
-
{{i18n "admin.api.key"}}
- {{#if model.api_key}}
-
- {{model.api_key.key}}
- {{d-button
- class="btn-default"
- action=(action "regenerateApiKey")
- icon="undo"
- label="admin.api.regenerate"}}
- {{d-button
- class="btn-default"
- action=(action "revokeApiKey")
- icon="times"
- label="admin.api.revoke"}}
-
- {{else}}
-
- —
-
-
- {{d-button
- class="btn-default"
- action=(action "generateApiKey")
- icon="key"
- label="admin.api.generate"}}
-
- {{/if}}
+
{{i18n "admin.api.active_keys"}}
+
+ {{model.api_key_count}}
+
+
+ {{d-button href="/admin/api/keys" label="admin.api.manage_keys"}}
+
+
{{/if}}
diff --git a/app/assets/javascripts/admin/templates/users-list-show.hbs b/app/assets/javascripts/admin/templates/users-list-show.hbs
index 36cc552089..065d2ed93d 100644
--- a/app/assets/javascripts/admin/templates/users-list-show.hbs
+++ b/app/assets/javascripts/admin/templates/users-list-show.hbs
@@ -1,16 +1,22 @@
{{title}}
{{#if canCheckEmails}}
- {{#if showEmails}}
- {{i18n 'admin.users.hide_emails'}}
- {{else}}
- {{i18n 'admin.users.show_emails'}}
- {{/if}}
+ {{#if showEmails}}
+ {{d-button
+ action=(action "toggleEmailVisibility")
+ class="hide-emails btn-default"
+ label="admin.users.hide_emails"}}
+ {{else}}
+ {{d-button
+ action=(action "toggleEmailVisibility")
+ class="show-emails btn-default"
+ label="admin.users.show_emails"}}
+ {{/if}}
{{/if}}
+
{{text-field value=listFilter placeholder=searchHint}}
-
{{#load-more selector=".users-list tr" action=(action "loadMore")}}
diff --git a/app/assets/javascripts/discourse-common/lib/buffered-render.js.es6 b/app/assets/javascripts/discourse-common/lib/buffered-render.js.es6
index 8e23ba55ee..d3d301212a 100644
--- a/app/assets/javascripts/discourse-common/lib/buffered-render.js.es6
+++ b/app/assets/javascripts/discourse-common/lib/buffered-render.js.es6
@@ -1,3 +1,4 @@
+import { scheduleOnce } from "@ember/runloop";
// Ember 2.0 removes buffered rendering, but we can still implement it ourselves.
// In the long term we'll want to remove this.
@@ -13,7 +14,7 @@ const Mixin = {
},
rerenderBuffer() {
- Ember.run.scheduleOnce("render", this, this._customRender);
+ scheduleOnce("render", this, this._customRender);
}
};
diff --git a/app/assets/javascripts/discourse-common/lib/helpers.js.es6 b/app/assets/javascripts/discourse-common/lib/helpers.js.es6
index 907ae24d8c..5b7d4fdc81 100644
--- a/app/assets/javascripts/discourse-common/lib/helpers.js.es6
+++ b/app/assets/javascripts/discourse-common/lib/helpers.js.es6
@@ -1,7 +1,15 @@
-import { get } from "discourse-common/lib/raw-handlebars";
+import { get } from "@ember/object";
+import Helper from "@ember/component/helper";
+
+export function makeArray(obj) {
+ if (obj === null || obj === undefined) {
+ return [];
+ }
+ return Array.isArray(obj) ? obj : [obj];
+}
export function htmlHelper(fn) {
- return Ember.Helper.helper(function(...args) {
+ return Helper.helper(function(...args) {
args =
args.length > 1 ? args[0].concat({ hash: args[args.length - 1] }) : args;
return new Handlebars.SafeString(fn.apply(this, args) || "");
@@ -10,8 +18,19 @@ export function htmlHelper(fn) {
const _helpers = {};
+function rawGet(ctx, property, options) {
+ if (options.types && options.data.view) {
+ var view = options.data.view;
+ return view.getStream
+ ? view.getStream(property).value()
+ : view.getAttr(property);
+ } else {
+ return get(ctx, property);
+ }
+}
+
export function registerHelper(name, fn) {
- _helpers[name] = Ember.Helper.helper(fn);
+ _helpers[name] = Helper.helper(fn);
}
export function findHelper(name) {
@@ -39,7 +58,7 @@ function resolveParams(ctx, options) {
) {
params[k] = hash[k];
} else if (type === "ID" || type === "PathExpression") {
- params[k] = get(ctx, hash[k], options);
+ params[k] = rawGet(ctx, hash[k], options);
}
});
} else {
@@ -59,14 +78,14 @@ export function registerUnbound(name, fn) {
options.types &&
(options.types[i] === "ID" || options.types[i] === "PathExpression")
) {
- properties[i] = get(this, properties[i], options);
+ properties[i] = rawGet(this, properties[i], options);
}
}
return fn.call(this, ...properties, resolveParams(this, options));
};
- _helpers[name] = Ember.Helper.extend({
+ _helpers[name] = Helper.extend({
compute: (params, args) => fn(...params, args)
});
Handlebars.registerHelper(name, func);
diff --git a/app/assets/javascripts/discourse-common/lib/raw-handlebars-helpers.js.es6 b/app/assets/javascripts/discourse-common/lib/raw-handlebars-helpers.js.es6
new file mode 100644
index 0000000000..432ce98853
--- /dev/null
+++ b/app/assets/javascripts/discourse-common/lib/raw-handlebars-helpers.js.es6
@@ -0,0 +1,44 @@
+import { get } from "@ember/object";
+
+export function registerRawHelpers(hbs, handlebarsClass) {
+ hbs.helper = function() {};
+ hbs.helpers = Object.create(handlebarsClass.helpers);
+
+ hbs.helpers["get"] = function(context, options) {
+ var firstContext = options.contexts[0];
+ var val = firstContext[context];
+
+ if (context.indexOf("controller.") === 0) {
+ context = context.slice(context.indexOf(".") + 1);
+ }
+
+ return val === undefined ? get(firstContext, context) : val;
+ };
+
+ // #each .. in support (as format is transformed to this)
+ hbs.registerHelper("each", function(
+ localName,
+ inKeyword,
+ contextName,
+ options
+ ) {
+ var list = get(this, contextName);
+ var output = [];
+ var innerContext = Object.create(this);
+ for (var i = 0; i < list.length; i++) {
+ innerContext[localName] = list[i];
+ output.push(options.fn(innerContext));
+ }
+ return output.join("");
+ });
+
+ function stringCompatHelper(fn) {
+ const old = hbs.helpers[fn];
+ hbs.helpers[fn] = function(context, options) {
+ return old.apply(this, [hbs.helpers.get(context, options), options]);
+ };
+ }
+ stringCompatHelper("if");
+ stringCompatHelper("unless");
+ stringCompatHelper("with");
+}
diff --git a/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6 b/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6
index 5922fc55c8..eed8ec09a0 100644
--- a/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6
+++ b/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6
@@ -2,63 +2,8 @@
// templates are highly compatible with Ember so you don't need to worry about calling "get"
// and computed properties function, additionally it uses stringParams like Ember does
-// compat with ie8 in case this gets picked up elsewhere
-const objectCreate =
- Object.create ||
- function(parent) {
- function F() {}
- F.prototype = parent;
- return new F();
- };
-
const RawHandlebars = Handlebars.create();
-RawHandlebars.helper = function() {};
-RawHandlebars.helpers = objectCreate(Handlebars.helpers);
-
-RawHandlebars.helpers["get"] = function(context, options) {
- var firstContext = options.contexts[0];
- var val = firstContext[context];
-
- if (context.indexOf("controller.") === 0) {
- context = context.slice(context.indexOf(".") + 1);
- }
-
- return val === undefined ? Ember.get(firstContext, context) : val;
-};
-
-// adds compatability so this works with stringParams
-function stringCompatHelper(fn) {
- const old = RawHandlebars.helpers[fn];
- RawHandlebars.helpers[fn] = function(context, options) {
- return old.apply(this, [
- RawHandlebars.helpers.get(context, options),
- options
- ]);
- };
-}
-
-// #each .. in support (as format is transformed to this)
-RawHandlebars.registerHelper("each", function(
- localName,
- inKeyword,
- contextName,
- options
-) {
- var list = Ember.get(this, contextName);
- var output = [];
- var innerContext = objectCreate(this);
- for (var i = 0; i < list.length; i++) {
- innerContext[localName] = list[i];
- output.push(options.fn(innerContext));
- }
- return output.join("");
-});
-
-stringCompatHelper("if");
-stringCompatHelper("unless");
-stringCompatHelper("with");
-
function buildPath(blk, args) {
var result = {
type: "PathExpression",
@@ -113,14 +58,14 @@ function replaceGet(ast) {
if (Handlebars.Compiler) {
RawHandlebars.Compiler = function() {};
- RawHandlebars.Compiler.prototype = objectCreate(
+ RawHandlebars.Compiler.prototype = Object.create(
Handlebars.Compiler.prototype
);
RawHandlebars.Compiler.prototype.compiler = RawHandlebars.Compiler;
RawHandlebars.JavaScriptCompiler = function() {};
- RawHandlebars.JavaScriptCompiler.prototype = objectCreate(
+ RawHandlebars.JavaScriptCompiler.prototype = Object.create(
Handlebars.JavaScriptCompiler.prototype
);
RawHandlebars.JavaScriptCompiler.prototype.compiler =
@@ -171,17 +116,6 @@ if (Handlebars.Compiler) {
};
}
-RawHandlebars.get = function(ctx, property, options) {
- if (options.types && options.data.view) {
- var view = options.data.view;
- return view.getStream
- ? view.getStream(property).value()
- : view.getAttr(property);
- } else {
- return Ember.get(ctx, property);
- }
-};
-
export function template() {
return RawHandlebars.template.apply(this, arguments);
}
@@ -194,8 +128,4 @@ export function compile() {
return RawHandlebars.compile.apply(this, arguments);
}
-export function get() {
- return RawHandlebars.get.apply(this, arguments);
-}
-
export default RawHandlebars;
diff --git a/app/assets/javascripts/discourse-common/mixins/focus-event.js.es6 b/app/assets/javascripts/discourse-common/mixins/focus-event.js.es6
index c0395b53ac..974d73c958 100644
--- a/app/assets/javascripts/discourse-common/mixins/focus-event.js.es6
+++ b/app/assets/javascripts/discourse-common/mixins/focus-event.js.es6
@@ -1,10 +1,11 @@
+import { bind } from "@ember/runloop";
import { getOwner } from "discourse-common/lib/get-owner";
export default Ember.Mixin.create({
ready() {
this._super(...arguments);
- this._onChangeHandler = Ember.run.bind(this, this._onChange);
+ this._onChangeHandler = bind(this, this._onChange);
// Default to true
Discourse.set("hasFocus", true);
@@ -26,7 +27,7 @@ export default Ember.Mixin.create({
_onChange() {
const container = getOwner(this);
- const appEvents = container.lookup("app-events:main");
+ const appEvents = container.lookup("service:app-events");
if (document.visibilityState === "hidden") {
if (Discourse.hasFocus) {
diff --git a/app/assets/javascripts/discourse-common/resolver.js.es6 b/app/assets/javascripts/discourse-common/resolver.js.es6
index aeab2d45fa..e1507406bb 100644
--- a/app/assets/javascripts/discourse-common/resolver.js.es6
+++ b/app/assets/javascripts/discourse-common/resolver.js.es6
@@ -1,9 +1,7 @@
import { findHelper } from "discourse-common/lib/helpers";
+import { get } from "@ember/object";
import deprecated from "discourse-common/lib/deprecated";
-
-/* global requirejs, require */
-var classify = Ember.String.classify;
-var get = Ember.get;
+import { classify, dasherize } from "@ember/string";
const _options = {};
@@ -63,7 +61,7 @@ export function buildResolver(baseName) {
split[1] = split[1].replace(".templates", "").replace("/templates", "");
// Try slashes
- let dashed = Ember.String.dasherize(split[1].replace(/\./g, "/"));
+ let dashed = dasherize(split[1].replace(/\./g, "/"));
if (
requirejs.entries[appBase + dashed] ||
requirejs.entries[adminBase + dashed]
@@ -72,7 +70,7 @@ export function buildResolver(baseName) {
}
// Try with dashes instead of slashes
- dashed = Ember.String.dasherize(split[1].replace(/\./g, "-"));
+ dashed = dasherize(split[1].replace(/\./g, "-"));
if (
requirejs.entries[appBase + dashed] ||
requirejs.entries[adminBase + dashed]
@@ -86,7 +84,7 @@ export function buildResolver(baseName) {
customResolve(parsedName) {
// If we end with the name we want, use it. This allows us to define components within plugins.
const suffix = parsedName.type + "s/" + parsedName.fullNameWithoutType,
- dashed = Ember.String.dasherize(suffix),
+ dashed = dasherize(suffix),
moduleName = Object.keys(requirejs.entries).find(function(e) {
return (
e.indexOf(suffix, e.length - suffix.length) !== -1 ||
diff --git a/app/assets/javascripts/discourse-loader.js b/app/assets/javascripts/discourse-loader.js
index 3a86a00da1..5052771e91 100644
--- a/app/assets/javascripts/discourse-loader.js
+++ b/app/assets/javascripts/discourse-loader.js
@@ -1,18 +1,108 @@
var define, requirejs;
(function() {
-
- var MOVED_MODULES = {
- "discourse/views/list/post-count-or-badges": "discourse/raw-views/list/post-count-or-badges",
- "discourse/views/list/posts-count-column" : "discourse/raw-views/list/posts-count-column",
- "discourse/views/list/visited-line" : "discourse/raw-views/list/visited-line",
- "discourse/views/topic-list-header-column" : "discourse/raw-views/topic-list-header-column",
- "discourse/views/topic-status" : "discourse/raw-views/topic-status"
- };
+ // In future versions of ember we don't need this
+ var EMBER_MODULES = {};
+ if (typeof Ember !== "undefined") {
+ EMBER_MODULES = {
+ jquery: { default: $ },
+ "@ember/component": { default: Ember.Component },
+ "@ember/controller": {
+ default: Ember.Controller,
+ inject: Ember.inject.controller
+ },
+ "@ember/object": {
+ default: Ember.Object,
+ get: Ember.get,
+ getProperties: Ember.getProperties,
+ set: Ember.set,
+ setProperties: Ember.setProperties
+ },
+ "@ember/object/computed": {
+ default: Ember.computed,
+ alias: Ember.computed.alias,
+ and: Ember.computed.and,
+ bool: Ember.computed.bool,
+ collect: Ember.computed.collect,
+ deprecatingAlias: Ember.computed.deprecatingAlias,
+ empty: Ember.computed.empty,
+ equal: Ember.computed.equal,
+ filter: Ember.computed.filter,
+ filterBy: Ember.computed.filterBy,
+ gt: Ember.computed.gt,
+ gte: Ember.computed.gte,
+ intersect: Ember.computed.intersect,
+ lt: Ember.computed.lt,
+ lte: Ember.computed.lte,
+ map: Ember.computed.map,
+ mapBy: Ember.computed.mapBy,
+ match: Ember.computed.match,
+ max: Ember.computed.max,
+ min: Ember.computed.min,
+ none: Ember.computed.none,
+ not: Ember.computed.not,
+ notEmpty: Ember.computed.notEmpty,
+ oneWay: Ember.computed.oneWay,
+ or: Ember.computed.or,
+ readOnly: Ember.computed.readOnly,
+ reads: Ember.computed.reads,
+ setDiff: Ember.computed.setDiff,
+ sort: Ember.computed.sort,
+ sum: Ember.computed.sum,
+ union: Ember.computed.union,
+ uniq: Ember.computed.uniq,
+ uniqBy: Ember.computed.uniqBy
+ },
+ "@ember/object/mixin": { default: Ember.Mixin },
+ "@ember/object/proxy": { default: Ember.ObjectProxy },
+ "@ember/object/evented": { on: Ember.on },
+ "@ember/routing/route": { default: Ember.Route },
+ "@ember/runloop": {
+ bind: Ember.run.bind,
+ cancel: Ember.run.cancel,
+ debounce: Ember.testing ? Ember.run : Ember.run.debounce,
+ later: Ember.run.later,
+ next: Ember.run.next,
+ once: Ember.run.once,
+ run: Ember.run,
+ schedule: Ember.run.schedule,
+ scheduleOnce: Ember.run.scheduleOnce,
+ throttle: Ember.run.throttle
+ },
+ "@ember/service": {
+ default: Ember.Service,
+ inject: Ember.inject.service
+ },
+ "@ember/utils": {
+ isEmpty: Ember.isEmpty
+ },
+ "rsvp": {
+ Promise: Ember.RSVP.Promise,
+ hash: Ember.RSVP.hash,
+ all: Ember.RSVP.all
+ },
+ "@ember/string": {
+ dasherize: Ember.String.dasherize,
+ classify: Ember.String.classify,
+ underscore: Ember.String.underscore,
+ camelize: Ember.String.camelize
+ },
+ "@ember/template": {
+ htmlSafe: Ember.String.htmlSafe
+ },
+ "@ember/application": {
+ setOwner: Ember.setOwner,
+ getOwner: Ember.getOwner
+ },
+ "@ember/component/helper": {
+ default: Ember.Helper
+ }
+ };
+ }
var _isArray;
if (!Array.isArray) {
- _isArray = function (x) {
+ _isArray = function(x) {
return Object.prototype.toString.call(x) === "[object Array]";
};
} else {
@@ -34,28 +124,34 @@ var define, requirejs;
}
function unsupportedModule(length) {
- throw new Error("an unsupported module was defined, expected `define(name, deps, module)` instead got: `" + length + "` arguments to define`");
+ throw new Error(
+ "an unsupported module was defined, expected `define(name, deps, module)` instead got: `" +
+ length +
+ "` arguments to define`"
+ );
}
- var defaultDeps = ['require', 'exports', 'module'];
+ var defaultDeps = ["require", "exports", "module"];
function Module(name, deps, callback, exports) {
- this.id = uuid++;
- this.name = name;
- this.deps = !deps.length && callback.length ? defaultDeps : deps;
- this.exports = exports || { };
+ this.id = uuid++;
+ this.name = name;
+ this.deps = !deps.length && callback.length ? defaultDeps : deps;
+ this.exports = exports || {};
this.callback = callback;
- this.state = undefined;
- this._require = undefined;
+ this.state = undefined;
+ this._require = undefined;
}
-
Module.prototype.makeRequire = function() {
var name = this.name;
- return this._require || (this._require = function(dep) {
- return requirejs(resolve(dep, name));
- });
+ return (
+ this._require ||
+ (this._require = function(dep) {
+ return requirejs(resolve(dep, name));
+ })
+ );
};
define = function(name, deps, callback) {
@@ -65,7 +161,7 @@ var define, requirejs;
if (!_isArray(deps)) {
callback = deps;
- deps = [];
+ deps = [];
}
registry[name] = new Module(name, deps, callback);
@@ -74,7 +170,7 @@ var define, requirejs;
// we don't support all of AMD
// define.amd = {};
// we will support petals...
- define.petal = { };
+ define.petal = {};
function Alias(path) {
this.name = path;
@@ -91,15 +187,15 @@ var define, requirejs;
var dep;
// TODO: new Module
// TODO: seen refactor
- var module = { };
+ var module = {};
for (var i = 0, l = length; i < l; i++) {
dep = deps[i];
- if (dep === 'exports') {
+ if (dep === "exports") {
module.exports = reified[i] = rseen;
- } else if (dep === 'require') {
+ } else if (dep === "require") {
reified[i] = mod.makeRequire();
- } else if (dep === 'module') {
+ } else if (dep === "module") {
mod.exports = rseen;
module = reified[i] = mod;
} else {
@@ -114,30 +210,22 @@ var define, requirejs;
}
function requireFrom(name, origin) {
-
- var mod = registry[name];
+ var mod = EMBER_MODULES[name] || registry[name];
if (!mod) {
- var moved = MOVED_MODULES[name];
- if (moved) {
- console.warn("DEPRECATION: `" + name + "` was moved to `" + moved + "`"); // eslint-disable-line no-console
- }
- mod = registry[moved];
- }
-
- if (!mod) {
- throw new Error('Could not find module `' + name + '` imported from `' + origin + '`');
+ throw new Error(
+ "Could not find module `" + name + "` imported from `" + origin + "`"
+ );
}
return requirejs(name);
}
function missingModule(name) {
- throw new Error('Could not find module ' + name);
+ throw new Error("Could not find module " + name);
}
requirejs = require = function(name) {
-
- if (MOVED_MODULES[name]) {
- name = MOVED_MODULES[name];
+ if (EMBER_MODULES[name]) {
+ return EMBER_MODULES[name];
}
var mod = registry[name];
@@ -146,10 +234,11 @@ var define, requirejs;
mod = registry[mod.callback.name];
}
- if (!mod) { missingModule(name); }
+ if (!mod) {
+ missingModule(name);
+ }
- if (mod.state !== FAILED &&
- seen.hasOwnProperty(name)) {
+ if (mod.state !== FAILED && seen.hasOwnProperty(name)) {
return seen[name];
}
@@ -157,17 +246,20 @@ var define, requirejs;
var module;
var loaded = false;
- seen[name] = { }; // placeholder for run-time cycles
+ seen[name] = {}; // placeholder for run-time cycles
- tryFinally(function() {
- reified = reify(mod, name, seen[name]);
- module = mod.callback.apply(this, reified.deps);
- loaded = true;
- }, function() {
- if (!loaded) {
- mod.state = FAILED;
+ tryFinally(
+ function() {
+ reified = reify(mod, name, seen[name]);
+ module = mod.callback.apply(this, reified.deps);
+ loaded = true;
+ },
+ function() {
+ if (!loaded) {
+ mod.state = FAILED;
+ }
}
- });
+ );
var obj;
if (module === undefined && reified.module.exports) {
@@ -176,10 +268,12 @@ var define, requirejs;
obj = seen[name] = module;
}
- if (obj !== null &&
- (typeof obj === 'object' || typeof obj === 'function') &&
- obj['default'] === undefined) {
- obj['default'] = obj;
+ if (
+ obj !== null &&
+ (typeof obj === "object" || typeof obj === "function") &&
+ obj["default"] === undefined
+ ) {
+ obj["default"] = obj;
}
return (seen[name] = obj);
@@ -187,26 +281,30 @@ var define, requirejs;
window.requireModule = requirejs;
function resolve(child, name) {
- if (child.charAt(0) !== '.') { return child; }
+ if (child.charAt(0) !== ".") {
+ return child;
+ }
- var parts = child.split('/');
- var nameParts = name.split('/');
+ var parts = child.split("/");
+ var nameParts = name.split("/");
var parentBase = nameParts.slice(0, -1);
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
- if (part === '..') {
+ if (part === "..") {
if (parentBase.length === 0) {
- throw new Error('Cannot access parent module of root');
+ throw new Error("Cannot access parent module of root");
}
parentBase.pop();
- } else if (part === '.') {
+ } else if (part === ".") {
continue;
- } else { parentBase.push(part); }
+ } else {
+ parentBase.push(part);
+ }
}
- return parentBase.join('/');
+ return parentBase.join("/");
}
requirejs.entries = requirejs._eak_seen = registry;
diff --git a/app/assets/javascripts/discourse/adapters/post.js.es6 b/app/assets/javascripts/discourse/adapters/post.js.es6
index 5c3268daaa..950198067e 100644
--- a/app/assets/javascripts/discourse/adapters/post.js.es6
+++ b/app/assets/javascripts/discourse/adapters/post.js.es6
@@ -1,6 +1,7 @@
import { ajax } from "discourse/lib/ajax";
import RestAdapter from "discourse/adapters/rest";
import { Result } from "discourse/adapters/rest";
+import { underscore } from "@ember/string";
export default RestAdapter.extend({
find(store, type, findArgs) {
@@ -10,7 +11,7 @@ export default RestAdapter.extend({
},
createRecord(store, type, args) {
- const typeField = Ember.String.underscore(type);
+ const typeField = underscore(type);
args.nested_post = true;
return ajax(this.pathFor(store, type), { method: "POST", data: args }).then(
function(json) {
diff --git a/app/assets/javascripts/discourse/adapters/rest.js.es6 b/app/assets/javascripts/discourse/adapters/rest.js.es6
index b5ffc0f626..bc2839985f 100644
--- a/app/assets/javascripts/discourse/adapters/rest.js.es6
+++ b/app/assets/javascripts/discourse/adapters/rest.js.es6
@@ -1,5 +1,7 @@
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import { hashString } from "discourse/lib/hash";
+import { underscore } from "@ember/string";
const ADMIN_MODELS = [
"plugin",
@@ -24,7 +26,7 @@ function rethrow(error) {
throw error;
}
-export default Ember.Object.extend({
+export default EmberObject.extend({
storageKey(type, findArgs, options) {
if (options && options.cacheKey) {
return options.cacheKey;
@@ -65,10 +67,14 @@ export default Ember.Object.extend({
pathFor(store, type, findArgs) {
let path =
this.basePath(store, type, findArgs) +
- Ember.String.underscore(store.pluralize(type));
+ underscore(store.pluralize(this.apiNameFor(type)));
return this.appendQueryParams(path, findArgs);
},
+ apiNameFor(type) {
+ return type;
+ },
+
findAll(store, type, findArgs) {
return ajax(this.pathFor(store, type, findArgs)).catch(rethrow);
},
@@ -103,7 +109,7 @@ export default Ember.Object.extend({
update(store, type, id, attrs) {
const data = {};
- const typeField = Ember.String.underscore(type);
+ const typeField = underscore(this.apiNameFor(type));
data[typeField] = attrs;
return ajax(
@@ -116,7 +122,7 @@ export default Ember.Object.extend({
createRecord(store, type, attrs) {
const data = {};
- const typeField = Ember.String.underscore(type);
+ const typeField = underscore(this.apiNameFor(type));
data[typeField] = attrs;
return ajax(this.pathFor(store, type), this.getPayload("POST", data)).then(
function(json) {
diff --git a/app/assets/javascripts/discourse/components/about-page-users.js.es6 b/app/assets/javascripts/discourse/components/about-page-users.js.es6
index e2d65135db..7d4ff773ba 100644
--- a/app/assets/javascripts/discourse/components/about-page-users.js.es6
+++ b/app/assets/javascripts/discourse/components/about-page-users.js.es6
@@ -1,9 +1,10 @@
+import Component from "@ember/component";
import { userPath } from "discourse/lib/url";
import { formatUsername, escapeExpression } from "discourse/lib/utilities";
import { normalize } from "discourse/components/user-info";
import { renderAvatar } from "discourse/helpers/user-avatar";
-export default Ember.Component.extend({
+export default Component.extend({
usersTemplates: Ember.computed("users.[]", function() {
return (this.users || []).map(user => {
let name = "";
diff --git a/app/assets/javascripts/discourse/components/activation-controls.js.es6 b/app/assets/javascripts/discourse/components/activation-controls.js.es6
index d7d7fe800f..9b49ce7211 100644
--- a/app/assets/javascripts/discourse/components/activation-controls.js.es6
+++ b/app/assets/javascripts/discourse/components/activation-controls.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: "activation-controls"
});
diff --git a/app/assets/javascripts/discourse/components/add-category-tag-classes.js.es6 b/app/assets/javascripts/discourse/components/add-category-tag-classes.js.es6
index d5399dcfe7..d4a75e6ebe 100644
--- a/app/assets/javascripts/discourse/components/add-category-tag-classes.js.es6
+++ b/app/assets/javascripts/discourse/components/add-category-tag-classes.js.es6
@@ -1,6 +1,8 @@
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import { observes } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
_slug: null,
didInsertElement() {
@@ -25,7 +27,7 @@ export default Ember.Component.extend({
@observes("category.fullSlug", "tags")
refreshClass() {
- Ember.run.scheduleOnce("afterRender", this, this._updateClass);
+ scheduleOnce("afterRender", this, this._updateClass);
},
_removeClass() {
diff --git a/app/assets/javascripts/discourse/components/avatar-uploader.js.es6 b/app/assets/javascripts/discourse/components/avatar-uploader.js.es6
index 7349ce5a6b..3350ddff31 100644
--- a/app/assets/javascripts/discourse/components/avatar-uploader.js.es6
+++ b/app/assets/javascripts/discourse/components/avatar-uploader.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import UploadMixin from "discourse/mixins/upload";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
type: "avatar",
tagName: "span",
imageIsNotASquare: false,
diff --git a/app/assets/javascripts/discourse/components/backup-codes.js.es6 b/app/assets/javascripts/discourse/components/backup-codes.js.es6
index 51be5edccd..5e80cc3e3b 100644
--- a/app/assets/javascripts/discourse/components/backup-codes.js.es6
+++ b/app/assets/javascripts/discourse/components/backup-codes.js.es6
@@ -1,3 +1,4 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
// https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
@@ -12,7 +13,7 @@ function b64EncodeUnicode(str) {
);
}
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["backup-codes"],
backupCodes: null,
diff --git a/app/assets/javascripts/discourse/components/backup-uploader.js.es6 b/app/assets/javascripts/discourse/components/backup-uploader.js.es6
index 66b2665095..e75470439d 100644
--- a/app/assets/javascripts/discourse/components/backup-uploader.js.es6
+++ b/app/assets/javascripts/discourse/components/backup-uploader.js.es6
@@ -1,9 +1,11 @@
+import Component from "@ember/component";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
import UploadMixin from "discourse/mixins/upload";
+import { on } from "@ember/object/evented";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
tagName: "span",
@computed("uploading", "uploadProgress")
@@ -34,7 +36,7 @@ export default Ember.Component.extend(UploadMixin, {
};
},
- _init: function() {
+ _init: on("didInsertElement", function() {
const $upload = $(this.element);
$upload.on("fileuploadadd", (e, data) => {
@@ -47,5 +49,5 @@ export default Ember.Component.extend(UploadMixin, {
})
.catch(popupAjaxError);
});
- }.on("didInsertElement")
+ })
});
diff --git a/app/assets/javascripts/discourse/components/badge-button.js.es6 b/app/assets/javascripts/discourse/components/badge-button.js.es6
index d0c2708b66..dde5bfb804 100644
--- a/app/assets/javascripts/discourse/components/badge-button.js.es6
+++ b/app/assets/javascripts/discourse/components/badge-button.js.es6
@@ -1,6 +1,8 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "span",
classNameBindings: [
":user-badge",
@@ -14,5 +16,5 @@ export default Ember.Component.extend({
},
attributeBindings: ["data-badge-name", "title"],
- "data-badge-name": Ember.computed.alias("badge.name")
+ "data-badge-name": alias("badge.name")
});
diff --git a/app/assets/javascripts/discourse/components/badge-card.js.es6 b/app/assets/javascripts/discourse/components/badge-card.js.es6
index c4312447e9..f9380b11eb 100644
--- a/app/assets/javascripts/discourse/components/badge-card.js.es6
+++ b/app/assets/javascripts/discourse/components/badge-card.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { sanitize, emojiUnescape } from "discourse/lib/text";
-export default Ember.Component.extend({
+export default Component.extend({
size: "medium",
classNameBindings: [":badge-card", "size", "badge.slug"],
diff --git a/app/assets/javascripts/discourse/components/badge-selector.js.es6 b/app/assets/javascripts/discourse/components/badge-selector.js.es6
index 53ed8e385a..94c08c95ca 100644
--- a/app/assets/javascripts/discourse/components/badge-selector.js.es6
+++ b/app/assets/javascripts/discourse/components/badge-selector.js.es6
@@ -1,3 +1,4 @@
+import Component from "@ember/component";
import {
on,
observes,
@@ -6,7 +7,7 @@ import {
import { findRawTemplate } from "discourse/lib/raw-templates";
const { makeArray } = Ember;
-export default Ember.Component.extend({
+export default Component.extend({
@computed("placeholderKey")
placeholder(placeholderKey) {
return placeholderKey ? I18n.t(placeholderKey) : "";
diff --git a/app/assets/javascripts/discourse/components/badge-title.js.es6 b/app/assets/javascripts/discourse/components/badge-title.js.es6
index 117b1cc490..d7fd08c318 100644
--- a/app/assets/javascripts/discourse/components/badge-title.js.es6
+++ b/app/assets/javascripts/discourse/components/badge-title.js.es6
@@ -1,12 +1,18 @@
+import Component from "@ember/component";
import { ajax } from "discourse/lib/ajax";
-import BadgeSelectController from "discourse/mixins/badge-select-controller";
+import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend(BadgeSelectController, {
+export default Component.extend({
classNames: ["badge-title"],
saved: false,
saving: false,
+ @computed("selectableUserBadges", "selectedUserBadgeId")
+ selectedUserBadge(selectableUserBadges, selectedUserBadgeId) {
+ return selectableUserBadges.findBy("id", parseInt(selectedUserBadgeId));
+ },
+
actions: {
save() {
this.setProperties({ saved: false, saving: true });
diff --git a/app/assets/javascripts/discourse/components/basic-topic-list.js.es6 b/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
index e8af6acc94..64942198ed 100644
--- a/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
+++ b/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
@@ -1,8 +1,10 @@
+import { alias, not } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
- loadingMore: Ember.computed.alias("topicList.loadingMore"),
- loading: Ember.computed.not("loaded"),
+export default Component.extend({
+ loadingMore: alias("topicList.loadingMore"),
+ loading: not("loaded"),
@computed("topicList.loaded")
loaded() {
diff --git a/app/assets/javascripts/discourse/components/bread-crumbs.js.es6 b/app/assets/javascripts/discourse/components/bread-crumbs.js.es6
index cd8157c828..e420fcce7c 100644
--- a/app/assets/javascripts/discourse/components/bread-crumbs.js.es6
+++ b/app/assets/javascripts/discourse/components/bread-crumbs.js.es6
@@ -1,13 +1,15 @@
+import { alias, filter, or } from "@ember/object/computed";
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
// A breadcrumb including category drop downs
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: ["hidden:hidden", ":category-breadcrumb"],
tagName: "ol",
- parentCategory: Ember.computed.alias("category.parentCategory"),
+ parentCategory: alias("category.parentCategory"),
- parentCategories: Ember.computed.filter("categories", function(c) {
+ parentCategories: filter("categories", function(c) {
if (
c.id === this.site.get("uncategorized_category_id") &&
!this.siteSettings.allow_uncategorized_topics
@@ -33,7 +35,7 @@ export default Ember.Component.extend({
return this.site.mobileView && !category;
},
- firstCategory: Ember.computed.or("{parentCategory,category}"),
+ firstCategory: or("{parentCategory,category}"),
@computed("category", "parentCategory")
secondCategory(category, parentCategory) {
diff --git a/app/assets/javascripts/discourse/components/bulk-select-button.js.es6 b/app/assets/javascripts/discourse/components/bulk-select-button.js.es6
index 04d125b803..1070402ca0 100644
--- a/app/assets/javascripts/discourse/components/bulk-select-button.js.es6
+++ b/app/assets/javascripts/discourse/components/bulk-select-button.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import showModal from "discourse/lib/show-modal";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["bulk-select-container"],
actions: {
diff --git a/app/assets/javascripts/discourse/components/categories-and-latest-topics.js.es6 b/app/assets/javascripts/discourse/components/categories-and-latest-topics.js.es6
index 8da2cf8495..4f2b2c2497 100644
--- a/app/assets/javascripts/discourse/components/categories-and-latest-topics.js.es6
+++ b/app/assets/javascripts/discourse/components/categories-and-latest-topics.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["categories-and-latest"]
});
diff --git a/app/assets/javascripts/discourse/components/categories-and-top-topics.js.es6 b/app/assets/javascripts/discourse/components/categories-and-top-topics.js.es6
index 4f1c888692..7d9caf45c2 100644
--- a/app/assets/javascripts/discourse/components/categories-and-top-topics.js.es6
+++ b/app/assets/javascripts/discourse/components/categories-and-top-topics.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["categories-and-top"]
});
diff --git a/app/assets/javascripts/discourse/components/categories-boxes-topic.js.es6 b/app/assets/javascripts/discourse/components/categories-boxes-topic.js.es6
index c061cb55e9..b5536923ec 100644
--- a/app/assets/javascripts/discourse/components/categories-boxes-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/categories-boxes-topic.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "li",
@computed("topic.pinned", "topic.closed", "topic.archived")
diff --git a/app/assets/javascripts/discourse/components/categories-boxes-with-topics.js.es6 b/app/assets/javascripts/discourse/components/categories-boxes-with-topics.js.es6
index ed9e4a87a7..40b16d03fa 100644
--- a/app/assets/javascripts/discourse/components/categories-boxes-with-topics.js.es6
+++ b/app/assets/javascripts/discourse/components/categories-boxes-with-topics.js.es6
@@ -1,6 +1,8 @@
+import { isEmpty } from "@ember/utils";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "section",
classNameBindings: [
":category-boxes-with-topics",
@@ -10,7 +12,7 @@ export default Ember.Component.extend({
@computed("categories.[].uploaded_logo.url")
anyLogos() {
return this.categories.any(c => {
- return !Ember.isEmpty(c.get("uploaded_logo.url"));
+ return !isEmpty(c.get("uploaded_logo.url"));
});
}
});
diff --git a/app/assets/javascripts/discourse/components/categories-boxes.js.es6 b/app/assets/javascripts/discourse/components/categories-boxes.js.es6
index f78bfbfcd7..11b76ed1d4 100644
--- a/app/assets/javascripts/discourse/components/categories-boxes.js.es6
+++ b/app/assets/javascripts/discourse/components/categories-boxes.js.es6
@@ -1,7 +1,9 @@
+import { isEmpty } from "@ember/utils";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import DiscourseURL from "discourse/lib/url";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "section",
classNameBindings: [
":category-boxes",
@@ -11,12 +13,12 @@ export default Ember.Component.extend({
@computed("categories.[].uploaded_logo.url")
anyLogos() {
- return this.categories.any(c => !Ember.isEmpty(c.get("uploaded_logo.url")));
+ return this.categories.any(c => !isEmpty(c.get("uploaded_logo.url")));
},
@computed("categories.[].subcategories")
hasSubcategories() {
- return this.categories.any(c => !Ember.isEmpty(c.get("subcategories")));
+ return this.categories.any(c => !isEmpty(c.get("subcategories")));
},
click(e) {
diff --git a/app/assets/javascripts/discourse/components/categories-only.js.es6 b/app/assets/javascripts/discourse/components/categories-only.js.es6
index 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/discourse/components/categories-only.js.es6
+++ b/app/assets/javascripts/discourse/components/categories-only.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/discourse/components/categories-topic-list.js.es6 b/app/assets/javascripts/discourse/components/categories-topic-list.js.es6
index 9b102dc46c..ccc903e96e 100644
--- a/app/assets/javascripts/discourse/components/categories-topic-list.js.es6
+++ b/app/assets/javascripts/discourse/components/categories-topic-list.js.es6
@@ -1,2 +1,3 @@
+import Component from "@ember/component";
// Exists so plugins can use it
-export default Ember.Component.extend();
+export default Component.extend();
diff --git a/app/assets/javascripts/discourse/components/category-title-before.js.es6 b/app/assets/javascripts/discourse/components/category-title-before.js.es6
index 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/discourse/components/category-title-before.js.es6
+++ b/app/assets/javascripts/discourse/components/category-title-before.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/discourse/components/category-title-link.js.es6 b/app/assets/javascripts/discourse/components/category-title-link.js.es6
index 4a6fa5d604..c6dacce317 100644
--- a/app/assets/javascripts/discourse/components/category-title-link.js.es6
+++ b/app/assets/javascripts/discourse/components/category-title-link.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "h3"
});
diff --git a/app/assets/javascripts/discourse/components/category-unread.js.es6 b/app/assets/javascripts/discourse/components/category-unread.js.es6
index 1d3bdc0353..5bf9ae8df8 100644
--- a/app/assets/javascripts/discourse/components/category-unread.js.es6
+++ b/app/assets/javascripts/discourse/components/category-unread.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "span"
});
diff --git a/app/assets/javascripts/discourse/components/cdn-img.js.es6 b/app/assets/javascripts/discourse/components/cdn-img.js.es6
index f10b1d9e1e..338c71a1ee 100644
--- a/app/assets/javascripts/discourse/components/cdn-img.js.es6
+++ b/app/assets/javascripts/discourse/components/cdn-img.js.es6
@@ -1,6 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
+import { htmlSafe } from "@ember/template";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
@computed("src")
@@ -11,7 +13,7 @@ export default Ember.Component.extend({
@computed("width", "height")
style(width, height) {
if (width && height) {
- return Ember.String.htmlSafe(`--aspect-ratio: ${width / height};`);
+ return htmlSafe(`--aspect-ratio: ${width / height};`);
}
}
});
diff --git a/app/assets/javascripts/discourse/components/choose-message.js.es6 b/app/assets/javascripts/discourse/components/choose-message.js.es6
index 581cc361d5..cb6c251355 100644
--- a/app/assets/javascripts/discourse/components/choose-message.js.es6
+++ b/app/assets/javascripts/discourse/components/choose-message.js.es6
@@ -1,8 +1,12 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import debounce from "discourse/lib/debounce";
import { searchForTerm } from "discourse/lib/search";
import { observes } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
loading: null,
noResults: null,
messages: null,
@@ -29,7 +33,7 @@ export default Ember.Component.extend({
search: debounce(function(title) {
const currentTopicId = this.currentTopicId;
- if (Ember.isEmpty(title)) {
+ if (isEmpty(title)) {
this.setProperties({ messages: null, loading: false });
return;
}
@@ -54,11 +58,9 @@ export default Ember.Component.extend({
actions: {
chooseMessage(message) {
- const messageId = Ember.get(message, "id");
+ const messageId = get(message, "id");
this.set("selectedTopicId", messageId);
- Ember.run.next(() =>
- $(`#choose-message-${messageId}`).prop("checked", "true")
- );
+ next(() => $(`#choose-message-${messageId}`).prop("checked", "true"));
return false;
}
}
diff --git a/app/assets/javascripts/discourse/components/choose-topic.js.es6 b/app/assets/javascripts/discourse/components/choose-topic.js.es6
index 4ee45b5eee..f2d4792414 100644
--- a/app/assets/javascripts/discourse/components/choose-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/choose-topic.js.es6
@@ -1,8 +1,11 @@
+import { isEmpty } from "@ember/utils";
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import debounce from "discourse/lib/debounce";
import { searchForTerm } from "discourse/lib/search";
import { observes } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
loading: null,
noResults: null,
topics: null,
@@ -37,7 +40,7 @@ export default Ember.Component.extend({
const currentTopicId = this.currentTopicId;
- if (Ember.isEmpty(title)) {
+ if (isEmpty(title)) {
this.setProperties({ topics: null, loading: false });
return;
}
@@ -61,7 +64,7 @@ export default Ember.Component.extend({
actions: {
chooseTopic(topic) {
this.set("selectedTopicId", topic.id);
- Ember.run.next(() => {
+ next(() => {
document.getElementById(`choose-topic-${topic.id}`).checked = true;
});
return false;
diff --git a/app/assets/javascripts/discourse/components/color-picker-choice.js.es6 b/app/assets/javascripts/discourse/components/color-picker-choice.js.es6
index 8ea284b8f3..a1933193d2 100644
--- a/app/assets/javascripts/discourse/components/color-picker-choice.js.es6
+++ b/app/assets/javascripts/discourse/components/color-picker-choice.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "button",
attributeBindings: ["style", "title"],
classNameBindings: [":colorpicker", "isUsed:used-color:unused-color"],
diff --git a/app/assets/javascripts/discourse/components/color-picker.js.es6 b/app/assets/javascripts/discourse/components/color-picker.js.es6
index 8fc84886c7..c50fe34d6c 100644
--- a/app/assets/javascripts/discourse/components/color-picker.js.es6
+++ b/app/assets/javascripts/discourse/components/color-picker.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: "colors-container",
actions: {
diff --git a/app/assets/javascripts/discourse/components/composer-action-title.js.es6 b/app/assets/javascripts/discourse/components/composer-action-title.js.es6
index c4e014c5f7..8e4fd6c9f7 100644
--- a/app/assets/javascripts/discourse/components/composer-action-title.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-action-title.js.es6
@@ -1,3 +1,5 @@
+import { alias, equal } from "@ember/object/computed";
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
import {
PRIVATE_MESSAGE,
@@ -16,11 +18,11 @@ const TITLES = {
[EDIT_SHARED_DRAFT]: "composer.edit_shared_draft"
};
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["composer-action-title"],
- options: Ember.computed.alias("model.replyOptions"),
- action: Ember.computed.alias("model.action"),
- isEditing: Ember.computed.equal("action", EDIT),
+ options: alias("model.replyOptions"),
+ action: alias("model.action"),
+ isEditing: equal("action", EDIT),
@computed("options", "action")
actionTitle(opts, action) {
diff --git a/app/assets/javascripts/discourse/components/composer-body.js.es6 b/app/assets/javascripts/discourse/components/composer-body.js.es6
index 301e22452f..f265917279 100644
--- a/app/assets/javascripts/discourse/components/composer-body.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-body.js.es6
@@ -1,3 +1,9 @@
+import { throttle } from "@ember/runloop";
+import { run } from "@ember/runloop";
+import { cancel } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes
@@ -20,7 +26,7 @@ function mouseYPos(e) {
return e.clientY || (e.touches && e.touches[0] && e.touches[0].clientY);
}
-export default Ember.Component.extend(KeyEnterEscape, {
+export default Component.extend(KeyEnterEscape, {
elementId: "reply-control",
classNameBindings: [
@@ -59,7 +65,7 @@ export default Ember.Component.extend(KeyEnterEscape, {
"composer.canEditTopicFeaturedLink"
)
resize() {
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
@@ -77,8 +83,8 @@ export default Ember.Component.extend(KeyEnterEscape, {
// One second from now, check to see if the last key was hit when
// we recorded it. If it was, the user paused typing.
- Ember.run.cancel(this._lastKeyTimeout);
- this._lastKeyTimeout = Ember.run.later(() => {
+ cancel(this._lastKeyTimeout);
+ this._lastKeyTimeout = later(() => {
if (lastKeyUp !== this._lastKeyUp) {
return;
}
@@ -115,7 +121,7 @@ export default Ember.Component.extend(KeyEnterEscape, {
const throttledPerformDrag = (event => {
event.preventDefault();
- Ember.run.throttle(this, performDrag, event, THROTTLE_RATE);
+ throttle(this, performDrag, event, THROTTLE_RATE);
}).bind(this);
const endDrag = () => {
@@ -152,7 +158,7 @@ export default Ember.Component.extend(KeyEnterEscape, {
this._super(...arguments);
this.setupComposerResizeEvents();
- const resize = () => Ember.run(() => this.resize());
+ const resize = () => run(() => this.resize());
const triggerOpen = () => {
if (this.get("composer.composeState") === Composer.OPEN) {
this.appEvents.trigger("composer:opened");
diff --git a/app/assets/javascripts/discourse/components/composer-editor.js.es6 b/app/assets/javascripts/discourse/components/composer-editor.js.es6
index 3c204ec0c7..876851b658 100644
--- a/app/assets/javascripts/discourse/components/composer-editor.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-editor.js.es6
@@ -1,3 +1,9 @@
+import { throttle } from "@ember/runloop";
+import { next } from "@ember/runloop";
+import { debounce } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
import userSearch from "discourse/lib/user-search";
import {
default as computed,
@@ -53,7 +59,7 @@ export function addComposerUploadHandler(extensions, method) {
});
}
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: ["showToolbar:toolbar-visible", ":wmd-controls"],
uploadProgress: 0,
@@ -182,7 +188,7 @@ export default Ember.Component.extend({
transformComplete: v => v.username || v.name,
afterComplete() {
// ensures textarea scroll position is correct
- Ember.run.scheduleOnce("afterRender", () => $input.blur().focus());
+ scheduleOnce("afterRender", () => $input.blur().focus());
}
});
}
@@ -191,24 +197,10 @@ export default Ember.Component.extend({
this._initInputPreviewSync($input, $preview);
} else {
$input.on("scroll", () =>
- Ember.run.throttle(
- this,
- this._syncEditorAndPreviewScroll,
- $input,
- $preview,
- 20
- )
+ throttle(this, this._syncEditorAndPreviewScroll, $input, $preview, 20)
);
}
- if (!this.site.mobileView) {
- $preview
- .off("touchstart mouseenter", "img")
- .on("touchstart mouseenter", "img", () => {
- this._placeImageScaleButtons($preview);
- });
- }
-
// Focus on the body unless we have a title
if (
!this.get("composer.canEditTitle") &&
@@ -323,7 +315,7 @@ export default Ember.Component.extend({
this.appEvents.on(event, this, this._resetShouldBuildScrollMap);
});
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
$input.on("touchstart mouseenter", () => {
if (!$preview.is(":visible")) return;
$preview.off("scroll");
@@ -349,7 +341,7 @@ export default Ember.Component.extend({
this.set("shouldBuildScrollMap", false);
}
- Ember.run.throttle(this, $callback, $input, $preview, this.scrollMap, 20);
+ throttle(this, $callback, $input, $preview, this.scrollMap, 20);
},
_teardownInputPreviewSync() {
@@ -566,7 +558,7 @@ export default Ember.Component.extend({
},
_warnMentionedGroups($preview) {
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
var found = this.warnedGroupMentions || [];
$preview.find(".mention-group.notify").each((idx, e) => {
const $e = $(e);
@@ -590,16 +582,11 @@ export default Ember.Component.extend({
_warnCannotSeeMention($preview) {
const composerDraftKey = this.get("composer.draftKey");
- if (
- composerDraftKey === Composer.CREATE_TOPIC ||
- composerDraftKey === Composer.NEW_PRIVATE_MESSAGE_KEY ||
- composerDraftKey === Composer.REPLY_AS_NEW_TOPIC_KEY ||
- composerDraftKey === Composer.REPLY_AS_NEW_PRIVATE_MESSAGE_KEY
- ) {
+ if (composerDraftKey === Composer.NEW_PRIVATE_MESSAGE_KEY) {
return;
}
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
let found = this.warnedCannotSeeMentions || [];
$preview.find(".mention.cannot-see").each((idx, e) => {
@@ -609,7 +596,7 @@ export default Ember.Component.extend({
if (found.indexOf(name) === -1) {
// add a delay to allow for typing, so you don't open the warning right away
// previously we would warn after @bob even if you were about to mention @bob2
- Ember.run.later(
+ later(
this,
() => {
if (
@@ -630,7 +617,7 @@ export default Ember.Component.extend({
},
_resetUpload(removePlaceholder) {
- Ember.run.next(() => {
+ next(() => {
if (this._validUploads > 0) {
this._validUploads--;
}
@@ -849,7 +836,11 @@ export default Ember.Component.extend({
return;
}
- const replacement = match.replace(imageScaleRegex, `$1,${scale}%$3`);
+ const replacement = match.replace(
+ imageScaleRegex,
+ ``
+ );
+
this.appEvents.trigger(
"composer:replace-text",
matchingPlaceholder[index],
@@ -864,11 +855,18 @@ export default Ember.Component.extend({
// regex matches only upload placeholders with size defined,
// which is required for resizing
- // original string ``
- // match 1 ``
- const imageScaleRegex = /(!\[(?:\S*?(?=\|)\|)*?(?:\d{1,6}x\d{1,6})+?)(?:,?(\d{1,3})?%?)?(\]\(upload:\/\/\S*?\))/g;
+ // original string ``
+ // group 1 `image`
+ // group 2 `690x220`
+ // group 3 `, 50%`
+ // group 4 'upload://1TjaobgKObzpU7xRMw2HuUc87vO.png'
+ // group 4 'upload://1TjaobgKObzpU7xRMw2HuUc87vO.png "image title"'
+
+ // Notes:
+ // Group 3 is optional. group 4 can match images with or without a markdown title.
+ // All matches are whitespace tolerant as long it's still valid markdown
+
+ const imageScaleRegex = /!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?\]\((upload:\/\/.*?)\)/g;
// wraps previewed upload markdown in a codeblock in its own class to keep a track
// of indexes later on to replace the correct upload placeholder in the composer
@@ -909,9 +907,9 @@ export default Ember.Component.extend({
@on("willDestroyElement")
_composerClosed() {
this.appEvents.trigger("composer:will-close");
- Ember.run.next(() => {
+ next(() => {
// need to wait a bit for the "slide down" transition of the composer
- Ember.run.later(
+ later(
() => this.appEvents.trigger("composer:closed"),
Ember.testing ? 0 : 400
);
@@ -932,8 +930,6 @@ export default Ember.Component.extend({
},
showPreview() {
- const $preview = $(this.element.querySelector(".d-editor-preview-wrapper"));
- this._placeImageScaleButtons($preview);
this.send("togglePreview");
},
@@ -984,7 +980,7 @@ export default Ember.Component.extend({
// Paint mentions
const unseenMentions = linkSeenMentions($preview, this.siteSettings);
if (unseenMentions.length) {
- Ember.run.debounce(
+ debounce(
this,
this._renderUnseenMentions,
$preview,
@@ -999,7 +995,7 @@ export default Ember.Component.extend({
// Paint category hashtags
const unseenCategoryHashtags = linkSeenCategoryHashtags($preview);
if (unseenCategoryHashtags.length) {
- Ember.run.debounce(
+ debounce(
this,
this._renderUnseenCategoryHashtags,
$preview,
@@ -1012,7 +1008,7 @@ export default Ember.Component.extend({
if (this.siteSettings.tagging_enabled) {
const unseenTagHashtags = linkSeenTagHashtags($preview);
if (unseenTagHashtags.length) {
- Ember.run.debounce(
+ debounce(
this,
this._renderUnseenTagHashtags,
$preview,
@@ -1023,7 +1019,7 @@ export default Ember.Component.extend({
}
// Paint oneboxes
- Ember.run.debounce(
+ debounce(
this,
() => {
const oneboxes = {};
@@ -1082,9 +1078,7 @@ export default Ember.Component.extend({
);
}
- if (this.site.mobileView && $preview.is(":visible")) {
- this._placeImageScaleButtons($preview);
- }
+ this._placeImageScaleButtons($preview);
this.trigger("previewRefreshed", $preview);
this.afterRefresh($preview);
diff --git a/app/assets/javascripts/discourse/components/composer-message.js.es6 b/app/assets/javascripts/discourse/components/composer-message.js.es6
index 4cdda3fc49..6cb98b8018 100644
--- a/app/assets/javascripts/discourse/components/composer-message.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-message.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { getOwner } from "discourse-common/lib/get-owner";
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [":composer-popup", ":hidden", "message.extraClass"],
@computed("message.templateName")
diff --git a/app/assets/javascripts/discourse/components/composer-messages.js.es6 b/app/assets/javascripts/discourse/components/composer-messages.js.es6
index 6a01d33950..e9860973a2 100644
--- a/app/assets/javascripts/discourse/components/composer-messages.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-messages.js.es6
@@ -1,8 +1,12 @@
+import { not } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import LinkLookup from "discourse/lib/link-lookup";
let _messagesCache = {};
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [":composer-popup-container", "hidden"],
checkedMessages: false,
messages: null,
@@ -13,7 +17,7 @@ export default Ember.Component.extend({
_yourselfConfirm: null,
similarTopics: null,
- hidden: Ember.computed.not("composer.viewOpenOrFullscreen"),
+ hidden: not("composer.viewOpenOrFullscreen"),
didInsertElement() {
this._super(...arguments);
@@ -22,7 +26,7 @@ export default Ember.Component.extend({
this.appEvents.on("composer:find-similar", this, this._findSimilar);
this.appEvents.on("composer-messages:close", this, this._closeTop);
this.appEvents.on("composer-messages:create", this, this._create);
- Ember.run.scheduleOnce("afterRender", this, this.reset);
+ scheduleOnce("afterRender", this, this.reset);
},
willDestroyElement() {
@@ -121,7 +125,7 @@ export default Ember.Component.extend({
_create(info) {
this.reset();
- this.send("popup", Ember.Object.create(info));
+ this.send("popup", EmberObject.create(info));
},
_findSimilar() {
diff --git a/app/assets/javascripts/discourse/components/composer-title.js.es6 b/app/assets/javascripts/discourse/components/composer-title.js.es6
index 5302ab85f4..556b24bda8 100644
--- a/app/assets/javascripts/discourse/components/composer-title.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-title.js.es6
@@ -1,15 +1,22 @@
+import { alias, or } from "@ember/object/computed";
+import { next } from "@ember/runloop";
+import { debounce } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
import InputValidation from "discourse/models/input-validation";
-import { load, lookupCache } from "pretty-text/oneboxer";
+import { load } from "pretty-text/oneboxer";
+import { lookupCache } from "pretty-text/oneboxer-cache";
import { ajax } from "discourse/lib/ajax";
import afterTransition from "discourse/lib/after-transition";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["title-input"],
- watchForLink: Ember.computed.alias("composer.canEditTopicFeaturedLink"),
+ watchForLink: alias("composer.canEditTopicFeaturedLink"),
+ disabled: or("composer.loading", "composer.disableTitleInput"),
didInsertElement() {
this._super(...arguments);
@@ -22,7 +29,7 @@ export default Ember.Component.extend({
}
if (this.get("composer.titleLength") > 0) {
- Ember.run.debounce(this, this._titleChanged, 10);
+ debounce(this, this._titleChanged, 10);
}
},
@@ -77,13 +84,13 @@ export default Ember.Component.extend({
}
if (Ember.testing) {
- Ember.run.next(() =>
+ next(() =>
// not ideal but we don't want to run this in current
// runloop to avoid an error in console
this._checkForUrl()
);
} else {
- Ember.run.debounce(this, this._checkForUrl, 500);
+ debounce(this, this._checkForUrl, 500);
}
},
@@ -132,14 +139,14 @@ export default Ember.Component.extend({
})
.finally(() => {
this.set("composer.loading", false);
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element.querySelector("input")).putCursorAtEnd();
});
});
} else {
this._updatePost(loadOnebox);
this.set("composer.loading", false);
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element.querySelector("input")).putCursorAtEnd();
});
}
diff --git a/app/assets/javascripts/discourse/components/composer-toggles.js.es6 b/app/assets/javascripts/discourse/components/composer-toggles.js.es6
index f618e1ca61..9f0547d641 100644
--- a/app/assets/javascripts/discourse/components/composer-toggles.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-toggles.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
@computed("composeState")
diff --git a/app/assets/javascripts/discourse/components/composer-user-selector.js.es6 b/app/assets/javascripts/discourse/components/composer-user-selector.js.es6
index 04a1ba7dc5..3e9aa03784 100644
--- a/app/assets/javascripts/discourse/components/composer-user-selector.js.es6
+++ b/app/assets/javascripts/discourse/components/composer-user-selector.js.es6
@@ -1,9 +1,11 @@
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
showSelector: true,
shouldHide: false,
defaultUsernameCount: 0,
@@ -75,7 +77,7 @@ export default Ember.Component.extend({
toggleSelector() {
this.set("showSelector", true);
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element)
.find("input")
.focus();
diff --git a/app/assets/javascripts/discourse/components/conditional-loading-section.js.es6 b/app/assets/javascripts/discourse/components/conditional-loading-section.js.es6
index dd8f321635..fb6f310518 100644
--- a/app/assets/javascripts/discourse/components/conditional-loading-section.js.es6
+++ b/app/assets/javascripts/discourse/components/conditional-loading-section.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["conditional-loading-section"],
classNameBindings: ["isLoading"],
diff --git a/app/assets/javascripts/discourse/components/conditional-loading-spinner.js.es6 b/app/assets/javascripts/discourse/components/conditional-loading-spinner.js.es6
index e0353315fe..1c6e37ec03 100644
--- a/app/assets/javascripts/discourse/components/conditional-loading-spinner.js.es6
+++ b/app/assets/javascripts/discourse/components/conditional-loading-spinner.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [
":loading-container",
"containerClass",
diff --git a/app/assets/javascripts/discourse/components/connector-container.js.es6 b/app/assets/javascripts/discourse/components/connector-container.js.es6
index 905ec1058e..6c29674578 100644
--- a/app/assets/javascripts/discourse/components/connector-container.js.es6
+++ b/app/assets/javascripts/discourse/components/connector-container.js.es6
@@ -1 +1,2 @@
-export default Ember.Component.extend();
+import Component from "@ember/component";
+export default Component.extend();
diff --git a/app/assets/javascripts/discourse/components/cook-text.js.es6 b/app/assets/javascripts/discourse/components/cook-text.js.es6
index 3e345df054..256636a3c5 100644
--- a/app/assets/javascripts/discourse/components/cook-text.js.es6
+++ b/app/assets/javascripts/discourse/components/cook-text.js.es6
@@ -1,7 +1,9 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import { cookAsync } from "discourse/lib/text";
import { ajax } from "discourse/lib/ajax";
-const CookText = Ember.Component.extend({
+const CookText = Component.extend({
tagName: "",
cooked: null,
@@ -11,7 +13,7 @@ const CookText = Ember.Component.extend({
this.set("cooked", cooked);
// no choice but to defer this cause
// pretty text may only be loaded now
- Ember.run.next(() =>
+ next(() =>
window
.requireModule("pretty-text/upload-short-url")
.resolveAllShortUrls(ajax)
diff --git a/app/assets/javascripts/discourse/components/count-i18n.js.es6 b/app/assets/javascripts/discourse/components/count-i18n.js.es6
index 5ee48fb5ab..9bdb715dc5 100644
--- a/app/assets/javascripts/discourse/components/count-i18n.js.es6
+++ b/app/assets/javascripts/discourse/components/count-i18n.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { bufferedRender } from "discourse-common/lib/buffered-render";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
tagName: "span",
rerenderTriggers: ["count", "suffix"],
diff --git a/app/assets/javascripts/discourse/components/create-account.js.es6 b/app/assets/javascripts/discourse/components/create-account.js.es6
index 9d91b58b35..e382244dc9 100644
--- a/app/assets/javascripts/discourse/components/create-account.js.es6
+++ b/app/assets/javascripts/discourse/components/create-account.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["create-account"],
didInsertElement() {
diff --git a/app/assets/javascripts/discourse/components/create-topic-button.js.es6 b/app/assets/javascripts/discourse/components/create-topic-button.js.es6
index a03702e98e..b2ab306a12 100644
--- a/app/assets/javascripts/discourse/components/create-topic-button.js.es6
+++ b/app/assets/javascripts/discourse/components/create-topic-button.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "",
label: "topic.create"
});
diff --git a/app/assets/javascripts/discourse/components/create-topics-notice.js.es6 b/app/assets/javascripts/discourse/components/create-topics-notice.js.es6
index 1e7658cfd5..96c29f9081 100644
--- a/app/assets/javascripts/discourse/components/create-topics-notice.js.es6
+++ b/app/assets/javascripts/discourse/components/create-topics-notice.js.es6
@@ -1,8 +1,10 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { observes } from "ember-addons/ember-computed-decorators";
import LivePostCounts from "discourse/models/live-post-counts";
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: ["hidden:hidden", ":create-topics-notice"],
enabled: false,
@@ -11,7 +13,7 @@ export default Ember.Component.extend({
publicPostCount: null,
requiredTopics: 5,
- requiredPosts: Ember.computed.alias("siteSettings.tl1_requires_read_posts"),
+ requiredPosts: alias("siteSettings.tl1_requires_read_posts"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/components/csv-uploader.js.es6 b/app/assets/javascripts/discourse/components/csv-uploader.js.es6
index a37e10f3cc..6fa3792d36 100644
--- a/app/assets/javascripts/discourse/components/csv-uploader.js.es6
+++ b/app/assets/javascripts/discourse/components/csv-uploader.js.es6
@@ -1,7 +1,9 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import UploadMixin from "discourse/mixins/upload";
+import { on } from "@ember/object/evented";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
type: "csv",
tagName: "span",
uploadUrl: "/invites/upload_csv",
@@ -31,7 +33,7 @@ export default Ember.Component.extend(UploadMixin, {
return { autoUpload: false };
},
- _init: function() {
+ _init: on("didInsertElement", function() {
const $upload = $(this.element);
$upload.on("fileuploadadd", (e, data) => {
@@ -42,5 +44,5 @@ export default Ember.Component.extend(UploadMixin, {
result => (result ? data.submit() : data.abort())
);
});
- }.on("didInsertElement")
+ })
});
diff --git a/app/assets/javascripts/discourse/components/custom-html.js.es6 b/app/assets/javascripts/discourse/components/custom-html.js.es6
index b30649deb5..8dd3414e23 100644
--- a/app/assets/javascripts/discourse/components/custom-html.js.es6
+++ b/app/assets/javascripts/discourse/components/custom-html.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { getCustomHTML } from "discourse/helpers/custom-html";
import { getOwner } from "discourse-common/lib/get-owner";
-export default Ember.Component.extend({
+export default Component.extend({
triggerAppEvent: null,
init() {
diff --git a/app/assets/javascripts/discourse/components/d-button.js.es6 b/app/assets/javascripts/discourse/components/d-button.js.es6
index 2665e6e83b..359d058d24 100644
--- a/app/assets/javascripts/discourse/components/d-button.js.es6
+++ b/app/assets/javascripts/discourse/components/d-button.js.es6
@@ -1,14 +1,18 @@
+import { notEmpty, empty } from "@ember/object/computed";
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
import DiscourseURL from "discourse/lib/url";
-export default Ember.Component.extend({
+export default Component.extend({
// subclasses need this
layoutName: "components/d-button",
form: null,
+ type: "button",
+
tagName: "button",
- classNameBindings: [":btn", "noText", "btnType"],
+ classNameBindings: ["btnLink::btn", "btnLink", "noText", "btnType"],
attributeBindings: [
"form",
"disabled",
@@ -18,7 +22,9 @@ export default Ember.Component.extend({
"type"
],
- btnIcon: Ember.computed.notEmpty("icon"),
+ btnIcon: notEmpty("icon"),
+
+ btnLink: Ember.computed.equal("display", "link"),
@computed("icon", "translatedLabel")
btnType(icon, translatedLabel) {
@@ -29,7 +35,7 @@ export default Ember.Component.extend({
}
},
- noText: Ember.computed.empty("translatedLabel"),
+ noText: empty("translatedLabel"),
@computed("title")
translatedTitle: {
diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6
index dc2e9fe00a..3d926b9783 100644
--- a/app/assets/javascripts/discourse/components/d-editor.js.es6
+++ b/app/assets/javascripts/discourse/components/d-editor.js.es6
@@ -1,3 +1,10 @@
+import { next } from "@ember/runloop";
+import { debounce } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import { inject as service } from "@ember/service";
+import Component from "@ember/component";
/*global Mousetrap:true */
import {
default as computed,
@@ -22,6 +29,7 @@ import { translations } from "pretty-text/emoji/data";
import { emojiSearch, isSkinTonableEmoji } from "pretty-text/emoji";
import { emojiUrlFor } from "discourse/lib/text";
import showModal from "discourse/lib/show-modal";
+import { Promise } from "rsvp";
// Our head can be a static string or a function that returns a string
// based on input (like for numbered lists).
@@ -211,14 +219,14 @@ export function onToolbarCreate(func) {
addToolbarCallback(func);
}
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["d-editor"],
ready: false,
lastSel: null,
_mouseTrap: null,
showLink: true,
emojiPickerIsActive: false,
- emojiStore: Ember.inject.service("emoji-store"),
+ emojiStore: service("emoji-store"),
@computed("placeholder")
placeholderTranslated(placeholder) {
@@ -247,7 +255,7 @@ export default Ember.Component.extend({
this._applyEmojiAutocomplete($editorInput);
this._applyCategoryHashtagAutocomplete($editorInput);
- Ember.run.scheduleOnce("afterRender", this, this._readyNow);
+ scheduleOnce("afterRender", this, this._readyNow);
const mouseTrap = Mousetrap(this.element.querySelector(".d-editor-input"));
const shortcuts = this.get("toolbar.shortcuts");
@@ -346,7 +354,7 @@ export default Ember.Component.extend({
return;
}
this.set("preview", cooked);
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
if (this._state !== "inDOM") {
return;
}
@@ -370,7 +378,7 @@ export default Ember.Component.extend({
if (Ember.testing) {
this._updatePreview();
} else {
- Ember.run.debounce(this, this._updatePreview, 30);
+ debounce(this, this._updatePreview, 30);
}
},
@@ -430,17 +438,14 @@ export default Ember.Component.extend({
emojiPickerIsActive: true
});
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
const filterInput = document.querySelector(
".emoji-picker input[name='filter']"
);
if (filterInput) {
filterInput.value = v.term;
- Ember.run.later(
- () => filterInput.dispatchEvent(new Event("input")),
- 50
- );
+ later(() => filterInput.dispatchEvent(new Event("input")), 50);
}
});
@@ -449,7 +454,7 @@ export default Ember.Component.extend({
},
dataSource: term => {
- return new Ember.RSVP.Promise(resolve => {
+ return new Promise(resolve => {
const full = `:${term}`;
term = term.toLowerCase();
@@ -545,7 +550,7 @@ export default Ember.Component.extend({
},
_selectText(from, length) {
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
const textarea = this.element.querySelector("textarea.d-editor-input");
const $textarea = $(textarea);
const oldScrollPos = $textarea.scrollTop();
@@ -554,7 +559,7 @@ export default Ember.Component.extend({
}
textarea.selectionStart = from;
textarea.selectionEnd = from + length;
- Ember.run.next(() => $textarea.trigger("change"));
+ next(() => $textarea.trigger("change"));
$textarea.scrollTop(oldScrollPos);
});
},
@@ -783,7 +788,7 @@ export default Ember.Component.extend({
$textarea.val(value);
$textarea.prop("selectionStart", insert.length);
$textarea.prop("selectionEnd", insert.length);
- Ember.run.next(() => $textarea.trigger("change"));
+ next(() => $textarea.trigger("change"));
this._focusTextArea();
},
@@ -884,7 +889,7 @@ export default Ember.Component.extend({
// ensures textarea scroll position is correct
_focusTextArea() {
const textarea = this.element.querySelector("textarea.d-editor-input");
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
textarea.blur();
textarea.focus();
});
diff --git a/app/assets/javascripts/discourse/components/d-modal-body.js.es6 b/app/assets/javascripts/discourse/components/d-modal-body.js.es6
index 8e8f01b0bc..a8543095ab 100644
--- a/app/assets/javascripts/discourse/components/d-modal-body.js.es6
+++ b/app/assets/javascripts/discourse/components/d-modal-body.js.es6
@@ -1,4 +1,6 @@
-export default Ember.Component.extend({
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["modal-body"],
fixed: false,
dismissable: true,
@@ -13,7 +15,7 @@ export default Ember.Component.extend({
fixedParent.modal("show");
}
- Ember.run.scheduleOnce("afterRender", this, this._afterFirstRender);
+ scheduleOnce("afterRender", this, this._afterFirstRender);
this.appEvents.on("modal-body:flash", this, "_flash");
this.appEvents.on("modal-body:clearFlash", this, "_clearFlash");
},
diff --git a/app/assets/javascripts/discourse/components/d-modal-cancel.js.es6 b/app/assets/javascripts/discourse/components/d-modal-cancel.js.es6
index 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/discourse/components/d-modal-cancel.js.es6
+++ b/app/assets/javascripts/discourse/components/d-modal-cancel.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/discourse/components/d-modal.js.es6 b/app/assets/javascripts/discourse/components/d-modal.js.es6
index 8c46fc48e1..19d4d2264c 100644
--- a/app/assets/javascripts/discourse/components/d-modal.js.es6
+++ b/app/assets/javascripts/discourse/components/d-modal.js.es6
@@ -1,6 +1,8 @@
+import { next } from "@ember/runloop";
import { on } from "ember-addons/ember-computed-decorators";
+import Component from "@ember/component";
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [
":modal",
":d-modal",
@@ -31,11 +33,11 @@ export default Ember.Component.extend({
setUp() {
$("html").on("keydown.discourse-modal", e => {
if (e.which === 27 && this.dismissable) {
- Ember.run.next(() => $(".modal-header a.close").click());
+ next(() => $(".modal-header button.modal-close").click());
}
if (e.which === 13 && this.triggerClickOnEnter(e)) {
- Ember.run.next(() => $(".modal-footer .btn-primary").click());
+ next(() => $(".modal-footer .btn-primary").click());
}
});
@@ -72,7 +74,7 @@ export default Ember.Component.extend({
// Delegate click to modal close if clicked outside.
// We do this because some CSS of ours seems to cover
// the backdrop and makes it unclickable.
- $(".modal-header a.close").click();
+ $(".modal-header button.modal-close").click();
}
},
diff --git a/app/assets/javascripts/discourse/components/d-navigation.js.es6 b/app/assets/javascripts/discourse/components/d-navigation.js.es6
index 26870bcd02..b44ad95efd 100644
--- a/app/assets/javascripts/discourse/components/d-navigation.js.es6
+++ b/app/assets/javascripts/discourse/components/d-navigation.js.es6
@@ -1,7 +1,9 @@
+import { inject as service } from "@ember/service";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
- router: Ember.inject.service(),
+export default Component.extend({
+ router: service(),
persistedQueryParams: null,
tagName: "",
diff --git a/app/assets/javascripts/discourse/components/d-section.js.es6 b/app/assets/javascripts/discourse/components/d-section.js.es6
index 1f1d07a676..ef1da4b0a0 100644
--- a/app/assets/javascripts/discourse/components/d-section.js.es6
+++ b/app/assets/javascripts/discourse/components/d-section.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { scrollTop } from "discourse/mixins/scroll-top";
// Can add a body class from within a component, also will scroll to the top automatically.
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "section",
didInsertElement() {
diff --git a/app/assets/javascripts/discourse/components/date-input.js.es6 b/app/assets/javascripts/discourse/components/date-input.js.es6
index d29962c02c..927be37881 100644
--- a/app/assets/javascripts/discourse/components/date-input.js.es6
+++ b/app/assets/javascripts/discourse/components/date-input.js.es6
@@ -1,3 +1,5 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
/* global Pikaday:true */
import loadScript from "discourse/lib/load-script";
import {
@@ -5,7 +7,7 @@ import {
on
} from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["d-date-input"],
date: null,
_picker: null,
@@ -36,7 +38,7 @@ export default Ember.Component.extend({
_loadPikadayPicker(container) {
loadScript("/javascripts/pikaday.js").then(() => {
- Ember.run.next(() => {
+ next(() => {
const default_opts = {
field: this.element.querySelector(".date-picker"),
container: container || this.element,
diff --git a/app/assets/javascripts/discourse/components/date-picker.js.es6 b/app/assets/javascripts/discourse/components/date-picker.js.es6
index 2c7d073169..e9403326bb 100644
--- a/app/assets/javascripts/discourse/components/date-picker.js.es6
+++ b/app/assets/javascripts/discourse/components/date-picker.js.es6
@@ -1,3 +1,5 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
/* global Pikaday:true */
import loadScript from "discourse/lib/load-script";
import {
@@ -7,7 +9,7 @@ import {
const DATE_FORMAT = "YYYY-MM-DD";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["date-picker-wrapper"],
_picker: null,
value: null,
@@ -29,7 +31,7 @@ export default Ember.Component.extend({
_loadPikadayPicker(container) {
loadScript("/javascripts/pikaday.js").then(() => {
- Ember.run.next(() => {
+ next(() => {
const options = {
field: this.element.querySelector(".date-picker"),
container: container || null,
diff --git a/app/assets/javascripts/discourse/components/date-time-input-range.js.es6 b/app/assets/javascripts/discourse/components/date-time-input-range.js.es6
index 3754be93cd..ec048ec730 100644
--- a/app/assets/javascripts/discourse/components/date-time-input-range.js.es6
+++ b/app/assets/javascripts/discourse/components/date-time-input-range.js.es6
@@ -1,4 +1,6 @@
-export default Ember.Component.extend({
+import { equal } from "@ember/object/computed";
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["d-date-time-input-range"],
from: null,
@@ -10,8 +12,8 @@ export default Ember.Component.extend({
showToTime: true,
error: null,
- fromPanelActive: Ember.computed.equal("currentPanel", "from"),
- toPanelActive: Ember.computed.equal("currentPanel", "to"),
+ fromPanelActive: equal("currentPanel", "from"),
+ toPanelActive: equal("currentPanel", "to"),
_valid(state) {
if (state.to < state.from) {
diff --git a/app/assets/javascripts/discourse/components/date-time-input.js.es6 b/app/assets/javascripts/discourse/components/date-time-input.js.es6
index ce173e3d42..41b41a8d32 100644
--- a/app/assets/javascripts/discourse/components/date-time-input.js.es6
+++ b/app/assets/javascripts/discourse/components/date-time-input.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["d-date-time-input"],
date: null,
showTime: true,
diff --git a/app/assets/javascripts/discourse/components/desktop-notification-config.js.es6 b/app/assets/javascripts/discourse/components/desktop-notification-config.js.es6
index 612d9d9f89..112723ba12 100644
--- a/app/assets/javascripts/discourse/components/desktop-notification-config.js.es6
+++ b/app/assets/javascripts/discourse/components/desktop-notification-config.js.es6
@@ -1,3 +1,5 @@
+import { or } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import KeyValueStore from "discourse/lib/key-value-store";
import {
@@ -14,7 +16,7 @@ import {
const keyValueStore = new KeyValueStore(context);
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["controls"],
@computed("isNotSupported")
@@ -78,7 +80,7 @@ export default Ember.Component.extend({
}
},
- isEnabled: Ember.computed.or("isEnabledDesktop", "isEnabledPush"),
+ isEnabled: or("isEnabledDesktop", "isEnabledPush"),
isPushNotificationsPreferred() {
if (!this.site.mobileView) {
diff --git a/app/assets/javascripts/discourse/components/directory-item.js.es6 b/app/assets/javascripts/discourse/components/directory-item.js.es6
index 79902869c8..05c085c2e9 100644
--- a/app/assets/javascripts/discourse/components/directory-item.js.es6
+++ b/app/assets/javascripts/discourse/components/directory-item.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { propertyEqual } from "discourse/lib/computed";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "tr",
classNameBindings: ["me"],
me: propertyEqual("item.user.id", "currentUser.id")
diff --git a/app/assets/javascripts/discourse/components/directory-toggle.js.es6 b/app/assets/javascripts/discourse/components/directory-toggle.js.es6
index 6765568078..d45e9ce9e7 100644
--- a/app/assets/javascripts/discourse/components/directory-toggle.js.es6
+++ b/app/assets/javascripts/discourse/components/directory-toggle.js.es6
@@ -1,8 +1,9 @@
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
tagName: "th",
classNames: ["sortable"],
diff --git a/app/assets/javascripts/discourse/components/disabled-icon.js.es6 b/app/assets/javascripts/discourse/components/disabled-icon.js.es6
index e54647c155..433c5f4d72 100644
--- a/app/assets/javascripts/discourse/components/disabled-icon.js.es6
+++ b/app/assets/javascripts/discourse/components/disabled-icon.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "span",
classNameBindings: [":fa-stack"]
});
diff --git a/app/assets/javascripts/discourse/components/discourse-banner.js.es6 b/app/assets/javascripts/discourse/components/discourse-banner.js.es6
index 6a84f538ca..6c8b18ea1e 100644
--- a/app/assets/javascripts/discourse/components/discourse-banner.js.es6
+++ b/app/assets/javascripts/discourse/components/discourse-banner.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("user.dismissed_banner_key", "banner.key", "hide")
visible(dismissedBannerKey, bannerKey, hide) {
dismissedBannerKey =
diff --git a/app/assets/javascripts/discourse/components/discourse-linked-text.js.es6 b/app/assets/javascripts/discourse/components/discourse-linked-text.js.es6
index 17398e4a21..fe4e7fd9c8 100644
--- a/app/assets/javascripts/discourse/components/discourse-linked-text.js.es6
+++ b/app/assets/javascripts/discourse/components/discourse-linked-text.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "span",
@computed("text")
diff --git a/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6 b/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6
index 9f151dc1fe..ea07e0d5fe 100644
--- a/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6
+++ b/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "a",
classNameBindings: [":discourse-tag", "style", "tagClass"],
attributeBindings: ["href"],
diff --git a/app/assets/javascripts/discourse/components/discourse-topic.js.es6 b/app/assets/javascripts/discourse/components/discourse-topic.js.es6
index 7e3011fb6e..c9484f6264 100644
--- a/app/assets/javascripts/discourse/components/discourse-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/discourse-topic.js.es6
@@ -1,3 +1,9 @@
+import { alias } from "@ember/object/computed";
+import { throttle } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
import DiscourseURL from "discourse/lib/url";
import AddArchetypeClass from "discourse/mixins/add-archetype-class";
import ClickTrack from "discourse/lib/click-track";
@@ -14,12 +20,12 @@ function highlight(postNumber) {
$contents.on("animationend", () => $contents.removeClass("highlighted"));
}
-export default Ember.Component.extend(
+export default Component.extend(
AddArchetypeClass,
Scrolling,
MobileScrollDirection,
{
- userFilters: Ember.computed.alias("topic.userFilters"),
+ userFilters: alias("topic.userFilters"),
classNameBindings: [
"multiSelect",
"topic.archetype",
@@ -32,8 +38,8 @@ export default Ember.Component.extend(
menuVisible: true,
SHORT_POST: 1200,
- postStream: Ember.computed.alias("topic.postStream"),
- archetype: Ember.computed.alias("topic.archetype"),
+ postStream: alias("topic.postStream"),
+ archetype: alias("topic.archetype"),
dockAt: 0,
_lastShowTopic: null,
@@ -49,13 +55,13 @@ export default Ember.Component.extend(
const enteredAt = this.enteredAt;
if (enteredAt && this.lastEnteredAt !== enteredAt) {
this._lastShowTopic = null;
- Ember.run.schedule("afterRender", () => this.scrolled());
+ schedule("afterRender", () => this.scrolled());
this.set("lastEnteredAt", enteredAt);
}
},
_highlightPost(postNumber) {
- Ember.run.scheduleOnce("afterRender", null, highlight, postNumber);
+ scheduleOnce("afterRender", null, highlight, postNumber);
},
_hideTopicInHeader() {
@@ -77,7 +83,7 @@ export default Ember.Component.extend(
this.pauseHeaderTopicUpdate = true;
this._lastShowTopic = true;
- Ember.run.later(() => {
+ later(() => {
this._lastShowTopic = false;
this.pauseHeaderTopicUpdate = false;
}, debounceDuration);
@@ -191,7 +197,7 @@ export default Ember.Component.extend(
// at the start of the scroll. This feels a lot more snappy compared to waiting
// for the scroll to end if we debounce.
if (this.site.mobileView && this.hasScrolled) {
- Ember.run.throttle(
+ throttle(
this,
this.calculateDirection,
offset,
diff --git a/app/assets/javascripts/discourse/components/discovery-categories.js.es6 b/app/assets/javascripts/discourse/components/discovery-categories.js.es6
index 97bbc33009..d5c70bbf9a 100644
--- a/app/assets/javascripts/discourse/components/discovery-categories.js.es6
+++ b/app/assets/javascripts/discourse/components/discovery-categories.js.es6
@@ -1,9 +1,10 @@
+import Component from "@ember/component";
import UrlRefresh from "discourse/mixins/url-refresh";
import { on } from "ember-addons/ember-computed-decorators";
const CATEGORIES_LIST_BODY_CLASS = "categories-list";
-export default Ember.Component.extend(UrlRefresh, {
+export default Component.extend(UrlRefresh, {
classNames: ["contents"],
@on("didInsertElement")
diff --git a/app/assets/javascripts/discourse/components/discovery-topics-list.js.es6 b/app/assets/javascripts/discourse/components/discovery-topics-list.js.es6
index 10a73fcd5e..6706cacd4a 100644
--- a/app/assets/javascripts/discourse/components/discovery-topics-list.js.es6
+++ b/app/assets/javascripts/discourse/components/discovery-topics-list.js.es6
@@ -1,60 +1,52 @@
+import { schedule } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import { on, observes } from "ember-addons/ember-computed-decorators";
import LoadMore from "discourse/mixins/load-more";
import UrlRefresh from "discourse/mixins/url-refresh";
-const DiscoveryTopicsListComponent = Ember.Component.extend(
- UrlRefresh,
- LoadMore,
- {
- classNames: ["contents"],
- eyelineSelector: ".topic-list-item",
+const DiscoveryTopicsListComponent = Component.extend(UrlRefresh, LoadMore, {
+ classNames: ["contents"],
+ eyelineSelector: ".topic-list-item",
- @on("didInsertElement")
- @observes("model")
- _readjustScrollPosition() {
- const scrollTo = this.session.get("topicListScrollPosition");
- if (scrollTo && scrollTo >= 0) {
- Ember.run.schedule("afterRender", () =>
- $(window).scrollTop(scrollTo + 1)
- );
- } else {
- Ember.run.scheduleOnce("afterRender", this, this.loadMoreUnlessFull);
- }
- },
+ @on("didInsertElement")
+ @observes("model")
+ _readjustScrollPosition() {
+ const scrollTo = this.session.get("topicListScrollPosition");
+ if (scrollTo && scrollTo >= 0) {
+ schedule("afterRender", () => $(window).scrollTop(scrollTo + 1));
+ } else {
+ scheduleOnce("afterRender", this, this.loadMoreUnlessFull);
+ }
+ },
- @observes("topicTrackingState.states")
- _updateTopics() {
- this.topicTrackingState.updateTopics(this.model.topics);
- },
+ @observes("topicTrackingState.states")
+ _updateTopics() {
+ this.topicTrackingState.updateTopics(this.model.topics);
+ },
- @observes("incomingCount")
- _updateTitle() {
- Discourse.updateContextCount(this.incomingCount);
- },
+ @observes("incomingCount")
+ _updateTitle() {
+ Discourse.updateContextCount(this.incomingCount);
+ },
- saveScrollPosition() {
- this.session.set("topicListScrollPosition", $(window).scrollTop());
- },
+ saveScrollPosition() {
+ this.session.set("topicListScrollPosition", $(window).scrollTop());
+ },
- scrolled() {
- this._super(...arguments);
- this.saveScrollPosition();
- },
-
- actions: {
- loadMore() {
- Discourse.updateContextCount(0);
- this.model.loadMore().then(hasMoreResults => {
- Ember.run.schedule("afterRender", () => this.saveScrollPosition());
- if (!hasMoreResults) {
- this.eyeline.flushRest();
- } else if ($(window).height() >= $(document).height()) {
- this.send("loadMore");
- }
- });
- }
+ actions: {
+ loadMore() {
+ Discourse.updateContextCount(0);
+ this.model.loadMore().then(hasMoreResults => {
+ schedule("afterRender", () => this.saveScrollPosition());
+ if (!hasMoreResults) {
+ this.eyeline.flushRest();
+ } else if ($(window).height() >= $(document).height()) {
+ this.send("loadMore");
+ }
+ });
}
}
-);
+});
export default DiscoveryTopicsListComponent;
diff --git a/app/assets/javascripts/discourse/components/edit-category-general.js.es6 b/app/assets/javascripts/discourse/components/edit-category-general.js.es6
index 9988120e59..e94e2a77d2 100644
--- a/app/assets/javascripts/discourse/components/edit-category-general.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-general.js.es6
@@ -1,3 +1,5 @@
+import { isEmpty } from "@ember/utils";
+import { not } from "@ember/object/computed";
import { buildCategoryPanel } from "discourse/components/edit-category-panel";
import { categoryBadgeHTML } from "discourse/helpers/category-link";
import Category from "discourse/models/category";
@@ -10,9 +12,7 @@ export default buildCategoryPanel("general", {
this.foregroundColors = ["FFFFFF", "000000"];
},
- canSelectParentCategory: Ember.computed.not(
- "category.isUncategorizedCategory"
- ),
+ canSelectParentCategory: not("category.isUncategorizedCategory"),
uncategorizedSiteSettingLink: Discourse.getURL(
"/admin/site_settings/category/all_results?filter=allow_uncategorized_topics"
),
@@ -85,7 +85,7 @@ export default buildCategoryPanel("general", {
// We can change the parent if there are no children
@computed("category.id")
subCategories(categoryId) {
- if (Ember.isEmpty(categoryId)) {
+ if (isEmpty(categoryId)) {
return null;
}
return Category.list().filterBy("parent_category_id", categoryId);
diff --git a/app/assets/javascripts/discourse/components/edit-category-images.js.es6 b/app/assets/javascripts/discourse/components/edit-category-images.js.es6
index f7b03702ec..2e12268885 100644
--- a/app/assets/javascripts/discourse/components/edit-category-images.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-images.js.es6
@@ -1,3 +1,4 @@
+import EmberObject from "@ember/object";
import { buildCategoryPanel } from "discourse/components/edit-category-panel";
import { default as computed } from "ember-addons/ember-computed-decorators";
@@ -33,7 +34,7 @@ export default buildCategoryPanel("images").extend({
_deleteUpload(path) {
this.set(
path,
- Ember.Object.create({
+ EmberObject.create({
id: null,
url: null
})
@@ -43,7 +44,7 @@ export default buildCategoryPanel("images").extend({
_setFromUpload(path, upload) {
this.set(
path,
- Ember.Object.create({
+ EmberObject.create({
url: upload.url,
id: upload.id
})
diff --git a/app/assets/javascripts/discourse/components/edit-category-panel.js.es6 b/app/assets/javascripts/discourse/components/edit-category-panel.js.es6
index 6a45839cf7..3161e31f35 100644
--- a/app/assets/javascripts/discourse/components/edit-category-panel.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-panel.js.es6
@@ -1,11 +1,13 @@
-const EditCategoryPanel = Ember.Component.extend({});
+import { equal } from "@ember/object/computed";
+import Component from "@ember/component";
+const EditCategoryPanel = Component.extend({});
export default EditCategoryPanel;
export function buildCategoryPanel(tab, extras) {
return EditCategoryPanel.extend(
{
- activeTab: Ember.computed.equal("selectedTab", tab),
+ activeTab: equal("selectedTab", tab),
classNameBindings: [
":modal-tab",
"activeTab::hide",
diff --git a/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 b/app/assets/javascripts/discourse/components/edit-category-settings.js.es6
index c32f8b0553..5d692cc6eb 100644
--- a/app/assets/javascripts/discourse/components/edit-category-settings.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-settings.js.es6
@@ -1,3 +1,4 @@
+import { empty, and } from "@ember/object/computed";
import { setting } from "discourse/lib/computed";
import { buildCategoryPanel } from "discourse/components/edit-category-panel";
import computed from "ember-addons/ember-computed-decorators";
@@ -12,12 +13,12 @@ export function addCategorySortCriteria(criteria) {
export default buildCategoryPanel("settings", {
emailInEnabled: setting("email_in"),
showPositionInput: setting("fixed_category_positions"),
- isParentCategory: Ember.computed.empty("category.parent_category_id"),
- showSubcategoryListStyle: Ember.computed.and(
+ isParentCategory: empty("category.parent_category_id"),
+ showSubcategoryListStyle: and(
"category.show_subcategory_list",
"isParentCategory"
),
- isDefaultSortOrder: Ember.computed.empty("category.sort_order"),
+ isDefaultSortOrder: empty("category.sort_order"),
@computed
availableSubcategoryListStyles() {
diff --git a/app/assets/javascripts/discourse/components/edit-category-tab.js.es6 b/app/assets/javascripts/discourse/components/edit-category-tab.js.es6
index 5f2f6b4912..42be7233af 100644
--- a/app/assets/javascripts/discourse/components/edit-category-tab.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-tab.js.es6
@@ -1,7 +1,9 @@
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import { propertyEqual } from "discourse/lib/computed";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "li",
classNameBindings: ["active", "tabClassName"],
@@ -19,7 +21,7 @@ export default Ember.Component.extend({
didInsertElement() {
this._super(...arguments);
- Ember.run.scheduleOnce("afterRender", this, this._addToCollection);
+ scheduleOnce("afterRender", this, this._addToCollection);
},
_addToCollection: function() {
diff --git a/app/assets/javascripts/discourse/components/edit-category-tags.js.es6 b/app/assets/javascripts/discourse/components/edit-category-tags.js.es6
index 665975cf6b..aaca4b0e49 100644
--- a/app/assets/javascripts/discourse/components/edit-category-tags.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-tags.js.es6
@@ -1,10 +1,8 @@
+import { empty, and } from "@ember/object/computed";
import { buildCategoryPanel } from "discourse/components/edit-category-panel";
export default buildCategoryPanel("tags", {
- allowedTagsEmpty: Ember.computed.empty("category.allowed_tags"),
- allowedTagGroupsEmpty: Ember.computed.empty("category.allowed_tag_groups"),
- disableAllowGlobalTags: Ember.computed.and(
- "allowedTagsEmpty",
- "allowedTagGroupsEmpty"
- )
+ allowedTagsEmpty: empty("category.allowed_tags"),
+ allowedTagGroupsEmpty: empty("category.allowed_tag_groups"),
+ disableAllowGlobalTags: and("allowedTagsEmpty", "allowedTagGroupsEmpty")
});
diff --git a/app/assets/javascripts/discourse/components/edit-category-topic-template.js.es6 b/app/assets/javascripts/discourse/components/edit-category-topic-template.js.es6
index b1d5c79d81..c3254cc3d6 100644
--- a/app/assets/javascripts/discourse/components/edit-category-topic-template.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-topic-template.js.es6
@@ -1,9 +1,10 @@
+import { scheduleOnce } from "@ember/runloop";
import { buildCategoryPanel } from "discourse/components/edit-category-panel";
export default buildCategoryPanel("topic-template", {
_activeTabChanged: function() {
if (this.activeTab) {
- Ember.run.scheduleOnce("afterRender", () =>
+ scheduleOnce("afterRender", () =>
this.element.querySelector(".d-editor-input").focus()
);
}
diff --git a/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6 b/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6
index 1f65b8797d..5b774ca667 100644
--- a/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-topic-timer-form.js.es6
@@ -1,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import { alias, equal, or } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes,
@@ -13,23 +17,15 @@ import {
BUMP_TYPE
} from "discourse/controllers/edit-topic-timer";
-export default Ember.Component.extend({
- selection: Ember.computed.alias("topicTimer.status_type"),
- autoOpen: Ember.computed.equal("selection", OPEN_STATUS_TYPE),
- autoClose: Ember.computed.equal("selection", CLOSE_STATUS_TYPE),
- autoDelete: Ember.computed.equal("selection", DELETE_STATUS_TYPE),
- autoBump: Ember.computed.equal("selection", BUMP_TYPE),
- publishToCategory: Ember.computed.equal(
- "selection",
- PUBLISH_TO_CATEGORY_STATUS_TYPE
- ),
- reminder: Ember.computed.equal("selection", REMINDER_TYPE),
- showTimeOnly: Ember.computed.or(
- "autoOpen",
- "autoDelete",
- "reminder",
- "autoBump"
- ),
+export default Component.extend({
+ selection: alias("topicTimer.status_type"),
+ autoOpen: equal("selection", OPEN_STATUS_TYPE),
+ autoClose: equal("selection", CLOSE_STATUS_TYPE),
+ autoDelete: equal("selection", DELETE_STATUS_TYPE),
+ autoBump: equal("selection", BUMP_TYPE),
+ publishToCategory: equal("selection", PUBLISH_TO_CATEGORY_STATUS_TYPE),
+ reminder: equal("selection", REMINDER_TYPE),
+ showTimeOnly: or("autoOpen", "autoDelete", "reminder", "autoBump"),
@computed(
"topicTimer.updateTime",
@@ -39,7 +35,7 @@ export default Ember.Component.extend({
)
saveDisabled(updateTime, loading, publishToCategory, topicTimerCategoryId) {
return (
- Ember.isEmpty(updateTime) ||
+ isEmpty(updateTime) ||
loading ||
(publishToCategory && !topicTimerCategoryId)
);
@@ -72,7 +68,7 @@ export default Ember.Component.extend({
@observes("selection")
_updateBasedOnLastPost() {
if (!this.autoClose) {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
this.set("topicTimer.based_on_last_post", false);
});
}
diff --git a/app/assets/javascripts/discourse/components/emoji-picker.js.es6 b/app/assets/javascripts/discourse/components/emoji-picker.js.es6
index dfe6287c67..52f9e8add4 100644
--- a/app/assets/javascripts/discourse/components/emoji-picker.js.es6
+++ b/app/assets/javascripts/discourse/components/emoji-picker.js.es6
@@ -1,3 +1,5 @@
+import { inject as service } from "@ember/service";
+import Component from "@ember/component";
import { on, observes } from "ember-addons/ember-computed-decorators";
import { findRawTemplate } from "discourse/lib/raw-templates";
import { emojiUrlFor } from "discourse/lib/text";
@@ -15,9 +17,9 @@ const customEmojis = _.keys(extendedEmojiList()).map(code => {
return { code, src: emojiUrlFor(code) };
});
-export default Ember.Component.extend({
+export default Component.extend({
automaticPositioning: true,
- emojiStore: Ember.inject.service("emoji-store"),
+ emojiStore: service("emoji-store"),
close() {
this._unbindEvents();
diff --git a/app/assets/javascripts/discourse/components/emoji-uploader.js.es6 b/app/assets/javascripts/discourse/components/emoji-uploader.js.es6
index f3273d8322..37dfd5ea10 100644
--- a/app/assets/javascripts/discourse/components/emoji-uploader.js.es6
+++ b/app/assets/javascripts/discourse/components/emoji-uploader.js.es6
@@ -1,11 +1,13 @@
+import { notEmpty, not } from "@ember/object/computed";
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
import UploadMixin from "discourse/mixins/upload";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
type: "emoji",
uploadUrl: "/admin/customize/emojis",
- hasName: Ember.computed.notEmpty("name"),
- addDisabled: Ember.computed.not("hasName"),
+ hasName: notEmpty("name"),
+ addDisabled: not("hasName"),
uploadOptions() {
return {
diff --git a/app/assets/javascripts/discourse/components/expand-post.js.es6 b/app/assets/javascripts/discourse/components/expand-post.js.es6
index 4bd2b8d4a5..1302e76795 100644
--- a/app/assets/javascripts/discourse/components/expand-post.js.es6
+++ b/app/assets/javascripts/discourse/components/expand-post.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
expanded: null,
_loading: false,
diff --git a/app/assets/javascripts/discourse/components/expanding-text-area.js.es6 b/app/assets/javascripts/discourse/components/expanding-text-area.js.es6
index 064764713f..d2b980a8f2 100644
--- a/app/assets/javascripts/discourse/components/expanding-text-area.js.es6
+++ b/app/assets/javascripts/discourse/components/expanding-text-area.js.es6
@@ -1,10 +1,11 @@
+import { scheduleOnce } from "@ember/runloop";
import { on, observes } from "ember-addons/ember-computed-decorators";
import autosize from "discourse/lib/autosize";
export default Ember.TextArea.extend({
@on("didInsertElement")
_startWatching() {
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
$(this.element).focus();
autosize(this.element);
});
@@ -12,6 +13,7 @@ export default Ember.TextArea.extend({
@observes("value")
_updateAutosize() {
+ this.element.value = this.value;
const evt = document.createEvent("Event");
evt.initEvent("autosize:update", true, false);
this.element.dispatchEvent(evt);
diff --git a/app/assets/javascripts/discourse/components/featured-topic.js.es6 b/app/assets/javascripts/discourse/components/featured-topic.js.es6
index eb0bde08ad..a975b893e9 100644
--- a/app/assets/javascripts/discourse/components/featured-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/featured-topic.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNameBindings: [":featured-topic"],
click(e) {
diff --git a/app/assets/javascripts/discourse/components/flag-action-type.js.es6 b/app/assets/javascripts/discourse/components/flag-action-type.js.es6
index 6a7a713d4e..c42818914d 100644
--- a/app/assets/javascripts/discourse/components/flag-action-type.js.es6
+++ b/app/assets/javascripts/discourse/components/flag-action-type.js.es6
@@ -1,7 +1,9 @@
+import { and, not, equal } from "@ember/object/computed";
+import Component from "@ember/component";
import { MAX_MESSAGE_LENGTH } from "discourse/models/post-action-type";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["flag-action-type"],
@computed("flag.name_key")
@@ -23,9 +25,9 @@ export default Ember.Component.extend({
return flag === selectedFlag;
},
- showMessageInput: Ember.computed.and("flag.is_custom_flag", "selected"),
- showDescription: Ember.computed.not("showMessageInput"),
- isNotifyUser: Ember.computed.equal("flag.name_key", "notify_user"),
+ showMessageInput: and("flag.is_custom_flag", "selected"),
+ showDescription: not("showMessageInput"),
+ isNotifyUser: equal("flag.name_key", "notify_user"),
@computed("flag.description", "flag.short_description")
description(long_description, short_description) {
diff --git a/app/assets/javascripts/discourse/components/flag-selection.js.es6 b/app/assets/javascripts/discourse/components/flag-selection.js.es6
index 8499713ce2..b52f544907 100644
--- a/app/assets/javascripts/discourse/components/flag-selection.js.es6
+++ b/app/assets/javascripts/discourse/components/flag-selection.js.es6
@@ -1,7 +1,9 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import { observes } from "ember-addons/ember-computed-decorators";
// Mostly hacks because `flag.hbs` didn't use `radio-button`
-export default Ember.Component.extend({
+export default Component.extend({
_selectRadio() {
this.element.querySelector("input[type='radio']").checked = false;
@@ -15,6 +17,6 @@ export default Ember.Component.extend({
@observes("nameKey")
selectedChanged() {
- Ember.run.next(this, this._selectRadio);
+ next(this, this._selectRadio);
}
});
diff --git a/app/assets/javascripts/discourse/components/flat-button.js.es6 b/app/assets/javascripts/discourse/components/flat-button.js.es6
index bcac9cc01f..1348836907 100644
--- a/app/assets/javascripts/discourse/components/flat-button.js.es6
+++ b/app/assets/javascripts/discourse/components/flat-button.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "button",
classNames: ["btn-flat"],
attributeBindings: ["disabled", "translatedTitle:title"],
diff --git a/app/assets/javascripts/discourse/components/footer-message.js.es6 b/app/assets/javascripts/discourse/components/footer-message.js.es6
index 22263eca31..e829a884c5 100644
--- a/app/assets/javascripts/discourse/components/footer-message.js.es6
+++ b/app/assets/javascripts/discourse/components/footer-message.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["footer-message"]
});
diff --git a/app/assets/javascripts/discourse/components/footer-nav.js.es6 b/app/assets/javascripts/discourse/components/footer-nav.js.es6
index 7ac143225a..d94910364e 100644
--- a/app/assets/javascripts/discourse/components/footer-nav.js.es6
+++ b/app/assets/javascripts/discourse/components/footer-nav.js.es6
@@ -1,3 +1,4 @@
+import { throttle } from "@ember/runloop";
import MountWidget from "discourse/components/mount-widget";
import MobileScrollDirection from "discourse/mixins/mobile-scroll-direction";
import Scrolling from "discourse/mixins/scrolling";
@@ -78,7 +79,7 @@ const FooterNavComponent = MountWidget.extend(
const offset = window.pageYOffset || $("html").scrollTop();
- Ember.run.throttle(
+ throttle(
this,
this.calculateDirection,
offset,
diff --git a/app/assets/javascripts/discourse/components/future-date-input.js.es6 b/app/assets/javascripts/discourse/components/future-date-input.js.es6
index 9386c1b3f7..8746cfb0ef 100644
--- a/app/assets/javascripts/discourse/components/future-date-input.js.es6
+++ b/app/assets/javascripts/discourse/components/future-date-input.js.es6
@@ -1,3 +1,6 @@
+import { isEmpty } from "@ember/utils";
+import { equal, and, empty } from "@ember/object/computed";
+import Component from "@ember/component";
import {
default as computed,
observes
@@ -5,17 +8,14 @@ import {
import { FORMAT } from "select-kit/components/future-date-input-selector";
import { PUBLISH_TO_CATEGORY_STATUS_TYPE } from "discourse/controllers/edit-topic-timer";
-export default Ember.Component.extend({
+export default Component.extend({
selection: null,
date: null,
time: null,
includeDateTime: true,
- isCustom: Ember.computed.equal("selection", "pick_date_and_time"),
- isBasedOnLastPost: Ember.computed.equal(
- "selection",
- "set_based_on_last_post"
- ),
- displayDateAndTimePicker: Ember.computed.and("includeDateTime", "isCustom"),
+ isCustom: equal("selection", "pick_date_and_time"),
+ isBasedOnLastPost: equal("selection", "set_based_on_last_post"),
+ displayDateAndTimePicker: and("includeDateTime", "isCustom"),
displayLabel: null,
init() {
@@ -36,7 +36,7 @@ export default Ember.Component.extend({
}
},
- timeInputDisabled: Ember.computed.empty("date"),
+ timeInputDisabled: empty("date"),
@observes("date", "time")
_updateInput() {
@@ -107,10 +107,7 @@ export default Ember.Component.extend({
) {
if (!statusType || willCloseImmediately) return false;
- if (
- statusType === PUBLISH_TO_CATEGORY_STATUS_TYPE &&
- Ember.isEmpty(categoryId)
- ) {
+ if (statusType === PUBLISH_TO_CATEGORY_STATUS_TYPE && isEmpty(categoryId)) {
return false;
}
diff --git a/app/assets/javascripts/discourse/components/generated-invite-link.js.es6 b/app/assets/javascripts/discourse/components/generated-invite-link.js.es6
index 74426a45b6..8b475cbbdb 100644
--- a/app/assets/javascripts/discourse/components/generated-invite-link.js.es6
+++ b/app/assets/javascripts/discourse/components/generated-invite-link.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
didInsertElement() {
this._super(...arguments);
$(this.element.querySelector("input"))
diff --git a/app/assets/javascripts/discourse/components/global-notice.js.es6 b/app/assets/javascripts/discourse/components/global-notice.js.es6
index 3d8c46679b..e16243f207 100644
--- a/app/assets/javascripts/discourse/components/global-notice.js.es6
+++ b/app/assets/javascripts/discourse/components/global-notice.js.es6
@@ -1,9 +1,11 @@
+import { bind } from "@ember/runloop";
+import Component from "@ember/component";
import { on } from "ember-addons/ember-computed-decorators";
import { iconHTML } from "discourse-common/lib/icon-library";
import LogsNotice from "discourse/services/logs-notice";
import { bufferedRender } from "discourse-common/lib/buffered-render";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
rerenderTriggers: ["site.isReadOnly", "siteSettings.disable_emails"],
@@ -65,7 +67,7 @@ export default Ember.Component.extend(
notices.push([
LogsNotice.currentProp("message"),
"alert-logs-notice",
- `${iconHTML("times")}
`
+ `${iconHTML("times")} `
]);
}
@@ -87,13 +89,10 @@ export default Ember.Component.extend(
@on("didInsertElement")
_setupLogsNotice() {
- this._boundRerenderBuffer = Ember.run.bind(this, this.rerenderBuffer);
+ this._boundRerenderBuffer = bind(this, this.rerenderBuffer);
LogsNotice.current().addObserver("hidden", this._boundRerenderBuffer);
- this._boundResetCurrentProp = Ember.run.bind(
- this,
- this._resetCurrentProp
- );
+ this._boundResetCurrentProp = bind(this, this._resetCurrentProp);
$(this.element).on(
"click.global-notice",
".alert-logs-notice .close",
diff --git a/app/assets/javascripts/discourse/components/google-search.js.es6 b/app/assets/javascripts/discourse/components/google-search.js.es6
index e99e862f8e..246e7ab2a3 100644
--- a/app/assets/javascripts/discourse/components/google-search.js.es6
+++ b/app/assets/javascripts/discourse/components/google-search.js.es6
@@ -1,10 +1,12 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["google-search-form"],
classNameBindings: ["hidden:hidden"],
- hidden: Ember.computed.alias("siteSettings.login_required"),
+ hidden: alias("siteSettings.login_required"),
@computed
siteUrl() {
diff --git a/app/assets/javascripts/discourse/components/group-activity-filter.js.es6 b/app/assets/javascripts/discourse/components/group-activity-filter.js.es6
index 145b770e51..790c675e49 100644
--- a/app/assets/javascripts/discourse/components/group-activity-filter.js.es6
+++ b/app/assets/javascripts/discourse/components/group-activity-filter.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "li"
});
diff --git a/app/assets/javascripts/discourse/components/group-card-contents.js.es6 b/app/assets/javascripts/discourse/components/group-card-contents.js.es6
index 2c3df56b1f..bd6d029e49 100644
--- a/app/assets/javascripts/discourse/components/group-card-contents.js.es6
+++ b/app/assets/javascripts/discourse/components/group-card-contents.js.es6
@@ -1,3 +1,5 @@
+import { alias, match, gt, or } from "@ember/object/computed";
+import Component from "@ember/component";
import { setting } from "discourse/lib/computed";
import { default as computed } from "ember-addons/ember-computed-decorators";
import CardContentsBase from "discourse/mixins/card-contents-base";
@@ -6,7 +8,7 @@ import { groupPath } from "discourse/lib/url";
const maxMembersToDisplay = 10;
-export default Ember.Component.extend(CardContentsBase, CleansUp, {
+export default Component.extend(CardContentsBase, CleansUp, {
elementId: "group-card",
triggeringLinkClass: "mention-group",
classNames: ["no-bg"],
@@ -20,11 +22,11 @@ export default Ember.Component.extend(CardContentsBase, CleansUp, {
allowBackgrounds: setting("allow_profile_backgrounds"),
showBadges: setting("enable_badges"),
- postStream: Ember.computed.alias("topic.postStream"),
- viewingTopic: Ember.computed.match("currentPath", /^topic\./),
+ postStream: alias("topic.postStream"),
+ viewingTopic: match("currentPath", /^topic\./),
- showMoreMembers: Ember.computed.gt("moreMembersCount", 0),
- hasMembersOrIsMember: Ember.computed.or(
+ showMoreMembers: gt("moreMembersCount", 0),
+ hasMembersOrIsMember: or(
"group.members",
"group.is_group_owner_display",
"group.is_group_user"
diff --git a/app/assets/javascripts/discourse/components/group-flair-inputs.js.es6 b/app/assets/javascripts/discourse/components/group-flair-inputs.js.es6
index f16d48827e..7b2b7110a0 100644
--- a/app/assets/javascripts/discourse/components/group-flair-inputs.js.es6
+++ b/app/assets/javascripts/discourse/components/group-flair-inputs.js.es6
@@ -1,10 +1,13 @@
+import { debounce } from "@ember/runloop";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { observes } from "ember-addons/ember-computed-decorators";
import { escapeExpression } from "discourse/lib/utilities";
import { convertIconClass } from "discourse-common/lib/icon-library";
import { ajax } from "discourse/lib/ajax";
+import { htmlSafe } from "@ember/template";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["group-flair-inputs"],
@computed
@@ -24,7 +27,7 @@ export default Ember.Component.extend({
@observes("model.flair_url")
_loadSVGIcon() {
- Ember.run.debounce(this, this._loadIcon, 1000);
+ debounce(this, this._loadIcon, 1000);
},
_loadIcon() {
@@ -75,7 +78,7 @@ export default Ember.Component.extend({
if (flairHexColor) style += `color: #${flairHexColor};`;
- return Ember.String.htmlSafe(style);
+ return htmlSafe(style);
},
@computed("model.flairBackgroundHexColor")
diff --git a/app/assets/javascripts/discourse/components/group-index-toggle.js.es6 b/app/assets/javascripts/discourse/components/group-index-toggle.js.es6
index 8a35118a89..247b7e1829 100644
--- a/app/assets/javascripts/discourse/components/group-index-toggle.js.es6
+++ b/app/assets/javascripts/discourse/components/group-index-toggle.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
tagName: "th",
classNames: ["sortable"],
diff --git a/app/assets/javascripts/discourse/components/group-manage-logs-filter.js.es6 b/app/assets/javascripts/discourse/components/group-manage-logs-filter.js.es6
index 0944c3ddf1..a6712bf498 100644
--- a/app/assets/javascripts/discourse/components/group-manage-logs-filter.js.es6
+++ b/app/assets/javascripts/discourse/components/group-manage-logs-filter.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
@computed("type")
diff --git a/app/assets/javascripts/discourse/components/group-manage-logs-row.js.es6 b/app/assets/javascripts/discourse/components/group-manage-logs-row.js.es6
index b7765f9620..acba43f2b7 100644
--- a/app/assets/javascripts/discourse/components/group-manage-logs-row.js.es6
+++ b/app/assets/javascripts/discourse/components/group-manage-logs-row.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "",
expandDetails: false,
diff --git a/app/assets/javascripts/discourse/components/group-manage-save-button.js.es6 b/app/assets/javascripts/discourse/components/group-manage-save-button.js.es6
index 1487151fde..726bfede36 100644
--- a/app/assets/javascripts/discourse/components/group-manage-save-button.js.es6
+++ b/app/assets/javascripts/discourse/components/group-manage-save-button.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
saving: null,
@computed("saving")
diff --git a/app/assets/javascripts/discourse/components/group-member.js.es6 b/app/assets/javascripts/discourse/components/group-member.js.es6
index be68373fa7..1c511cab15 100644
--- a/app/assets/javascripts/discourse/components/group-member.js.es6
+++ b/app/assets/javascripts/discourse/components/group-member.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["item"],
actions: {
diff --git a/app/assets/javascripts/discourse/components/group-members-input.js.es6 b/app/assets/javascripts/discourse/components/group-members-input.js.es6
index 8ef63b5a50..e1f701f96c 100644
--- a/app/assets/javascripts/discourse/components/group-members-input.js.es6
+++ b/app/assets/javascripts/discourse/components/group-members-input.js.es6
@@ -1,8 +1,11 @@
+import { isEmpty } from "@ember/utils";
+import { lte } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { propertyEqual } from "discourse/lib/computed";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["group-members-input"],
addButton: true,
@@ -28,7 +31,7 @@ export default Ember.Component.extend({
return !usernames || !(usernames.length > 0);
},
- showingFirst: Ember.computed.lte("currentPage", 1),
+ showingFirst: lte("currentPage", 1),
showingLast: propertyEqual("currentPage", "totalPages"),
actions: {
@@ -60,7 +63,7 @@ export default Ember.Component.extend({
},
addMembers() {
- if (Ember.isEmpty(this.get("model.usernames"))) {
+ if (isEmpty(this.get("model.usernames"))) {
return;
}
this.model.addMembers(this.get("model.usernames")).catch(popupAjaxError);
diff --git a/app/assets/javascripts/discourse/components/group-membership-button.js.es6 b/app/assets/javascripts/discourse/components/group-membership-button.js.es6
index 31ac171734..6b58c5370d 100644
--- a/app/assets/javascripts/discourse/components/group-membership-button.js.es6
+++ b/app/assets/javascripts/discourse/components/group-membership-button.js.es6
@@ -1,8 +1,9 @@
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
import showModal from "discourse/lib/show-modal";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["group-membership-button"],
@computed("model.public_admission", "userIsGroupUser")
diff --git a/app/assets/javascripts/discourse/components/group-navigation.js.es6 b/app/assets/javascripts/discourse/components/group-navigation.js.es6
index 91ad923ffc..89720fbbe8 100644
--- a/app/assets/javascripts/discourse/components/group-navigation.js.es6
+++ b/app/assets/javascripts/discourse/components/group-navigation.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: ""
});
diff --git a/app/assets/javascripts/discourse/components/group-post.js.es6 b/app/assets/javascripts/discourse/components/group-post.js.es6
index f94f36dc8d..5a3a096f49 100644
--- a/app/assets/javascripts/discourse/components/group-post.js.es6
+++ b/app/assets/javascripts/discourse/components/group-post.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("post.url")
postUrl: Discourse.getURL
});
diff --git a/app/assets/javascripts/discourse/components/group-selector.js.es6 b/app/assets/javascripts/discourse/components/group-selector.js.es6
index c70c51fbc7..4d4b431888 100644
--- a/app/assets/javascripts/discourse/components/group-selector.js.es6
+++ b/app/assets/javascripts/discourse/components/group-selector.js.es6
@@ -1,3 +1,5 @@
+import { isEmpty } from "@ember/utils";
+import Component from "@ember/component";
import {
on,
observes,
@@ -5,7 +7,7 @@ import {
} from "ember-addons/ember-computed-decorators";
import { findRawTemplate } from "discourse/lib/raw-templates";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("placeholderKey")
placeholder(placeholderKey) {
return placeholderKey ? I18n.t(placeholderKey) : "";
@@ -26,7 +28,7 @@ export default Ember.Component.extend({
allowAny: false,
items: _.isArray(groupNames)
? groupNames
- : Ember.isEmpty(groupNames)
+ : isEmpty(groupNames)
? []
: [groupNames],
single: this.single,
diff --git a/app/assets/javascripts/discourse/components/groups-form-interaction-fields.js.es6 b/app/assets/javascripts/discourse/components/groups-form-interaction-fields.js.es6
index f4756978a6..e4d1e6bb79 100644
--- a/app/assets/javascripts/discourse/components/groups-form-interaction-fields.js.es6
+++ b/app/assets/javascripts/discourse/components/groups-form-interaction-fields.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/components/groups-form-membership-fields.js.es6 b/app/assets/javascripts/discourse/components/groups-form-membership-fields.js.es6
index 7a9849463a..1115786b08 100644
--- a/app/assets/javascripts/discourse/components/groups-form-membership-fields.js.es6
+++ b/app/assets/javascripts/discourse/components/groups-form-membership-fields.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/components/groups-form-profile-fields.js.es6 b/app/assets/javascripts/discourse/components/groups-form-profile-fields.js.es6
index 15c2efbd96..98eabcea3f 100644
--- a/app/assets/javascripts/discourse/components/groups-form-profile-fields.js.es6
+++ b/app/assets/javascripts/discourse/components/groups-form-profile-fields.js.es6
@@ -1,3 +1,6 @@
+import { isEmpty } from "@ember/utils";
+import { not } from "@ember/object/computed";
+import Component from "@ember/component";
import {
default as computed,
observes
@@ -6,7 +9,7 @@ import Group from "discourse/models/group";
import InputValidation from "discourse/models/input-validation";
import debounce from "discourse/lib/debounce";
-export default Ember.Component.extend({
+export default Component.extend({
disableSave: null,
nameInput: null,
@@ -21,7 +24,7 @@ export default Ember.Component.extend({
}
},
- canEdit: Ember.computed.not("model.automatic"),
+ canEdit: not("model.automatic"),
@computed("basicNameValidation", "uniqueNameValidation")
nameValidation(basicNameValidation, uniqueNameValidation) {
@@ -63,7 +66,7 @@ export default Ember.Component.extend({
checkGroupName: debounce(function() {
name = this.nameInput;
- if (Ember.isEmpty(name)) return;
+ if (isEmpty(name)) return;
Group.checkName(name).then(response => {
const validationName = "uniqueNameValidation";
diff --git a/app/assets/javascripts/discourse/components/groups-info.js.es6 b/app/assets/javascripts/discourse/components/groups-info.js.es6
index a95c9da337..cf439ef7d0 100644
--- a/app/assets/javascripts/discourse/components/groups-info.js.es6
+++ b/app/assets/javascripts/discourse/components/groups-info.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "span",
classNames: ["group-info-details"],
diff --git a/app/assets/javascripts/discourse/components/hide-modal-trigger.js.es6 b/app/assets/javascripts/discourse/components/hide-modal-trigger.js.es6
index e3951d5277..df632e2557 100644
--- a/app/assets/javascripts/discourse/components/hide-modal-trigger.js.es6
+++ b/app/assets/javascripts/discourse/components/hide-modal-trigger.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
didInsertElement() {
this._super(...arguments);
$(".d-modal.fixed-modal")
diff --git a/app/assets/javascripts/discourse/components/highlight-text.js.es6 b/app/assets/javascripts/discourse/components/highlight-text.js.es6
index 6e8be431dc..a98ffdb653 100644
--- a/app/assets/javascripts/discourse/components/highlight-text.js.es6
+++ b/app/assets/javascripts/discourse/components/highlight-text.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import highlightText from "discourse/lib/highlight-text";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "span",
_highlightOnInsert: function() {
diff --git a/app/assets/javascripts/discourse/components/honeypot-input.js.es6 b/app/assets/javascripts/discourse/components/honeypot-input.js.es6
new file mode 100644
index 0000000000..06895b0586
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/honeypot-input.js.es6
@@ -0,0 +1,16 @@
+import { on } from "ember-addons/ember-computed-decorators";
+
+export default Ember.TextField.extend({
+ @on("init")
+ _init() {
+ // Chrome autocomplete is buggy per:
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=987293
+ // work around issue while leaving a semi useable honeypot for
+ // bots that are running full Chrome
+ if (navigator.userAgent.indexOf("Chrome") > -1) {
+ this.set("type", "text");
+ } else {
+ this.set("type", "password");
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/components/ignored-user-list-item.js.es6 b/app/assets/javascripts/discourse/components/ignored-user-list-item.js.es6
index 5bf27c13a1..6f26b5700b 100644
--- a/app/assets/javascripts/discourse/components/ignored-user-list-item.js.es6
+++ b/app/assets/javascripts/discourse/components/ignored-user-list-item.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "div",
items: null,
actions: {
diff --git a/app/assets/javascripts/discourse/components/ignored-user-list.js.es6 b/app/assets/javascripts/discourse/components/ignored-user-list.js.es6
index ac81cc505d..f73ac290e4 100644
--- a/app/assets/javascripts/discourse/components/ignored-user-list.js.es6
+++ b/app/assets/javascripts/discourse/components/ignored-user-list.js.es6
@@ -1,8 +1,9 @@
+import Component from "@ember/component";
import { popupAjaxError } from "discourse/lib/ajax-error";
import showModal from "discourse/lib/show-modal";
import User from "discourse/models/user";
-export default Ember.Component.extend({
+export default Component.extend({
item: null,
actions: {
removeIgnoredUser(item) {
diff --git a/app/assets/javascripts/discourse/components/image-uploader.js.es6 b/app/assets/javascripts/discourse/components/image-uploader.js.es6
index df9ce3e2b2..514a985223 100644
--- a/app/assets/javascripts/discourse/components/image-uploader.js.es6
+++ b/app/assets/javascripts/discourse/components/image-uploader.js.es6
@@ -1,10 +1,13 @@
+import { isEmpty } from "@ember/utils";
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import UploadMixin from "discourse/mixins/upload";
import lightbox from "discourse/lib/lightbox";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
classNames: ["image-uploader"],
loadingLightbox: false,
@@ -28,7 +31,7 @@ export default Ember.Component.extend(UploadMixin, {
@computed("placeholderUrl")
placeholderStyle(url) {
- if (Ember.isEmpty(url)) {
+ if (isEmpty(url)) {
return "".htmlSafe();
}
return `background-image: url(${url})`.htmlSafe();
@@ -36,7 +39,7 @@ export default Ember.Component.extend(UploadMixin, {
@computed("imageUrl")
imageCDNURL(url) {
- if (Ember.isEmpty(url)) {
+ if (isEmpty(url)) {
return "".htmlSafe();
}
@@ -50,7 +53,7 @@ export default Ember.Component.extend(UploadMixin, {
@computed("imageUrl")
imageBaseName(imageUrl) {
- if (Ember.isEmpty(imageUrl)) return;
+ if (isEmpty(imageUrl)) return;
return imageUrl.split("/").slice(-1)[0];
},
@@ -76,13 +79,13 @@ export default Ember.Component.extend(UploadMixin, {
},
_openLightbox() {
- Ember.run.next(() =>
+ next(() =>
$(this.element.querySelector("a.lightbox")).magnificPopup("open")
);
},
_applyLightbox() {
- if (this.imageUrl) Ember.run.next(() => lightbox($(this.element)));
+ if (this.imageUrl) next(() => lightbox($(this.element)));
},
actions: {
diff --git a/app/assets/javascripts/discourse/components/images-uploader.js.es6 b/app/assets/javascripts/discourse/components/images-uploader.js.es6
index 23b8fbe688..d3a9d6c3b7 100644
--- a/app/assets/javascripts/discourse/components/images-uploader.js.es6
+++ b/app/assets/javascripts/discourse/components/images-uploader.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import UploadMixin from "discourse/mixins/upload";
-export default Ember.Component.extend(UploadMixin, {
+export default Component.extend(UploadMixin, {
type: "avatar",
tagName: "span",
diff --git a/app/assets/javascripts/discourse/components/input-tip.js.es6 b/app/assets/javascripts/discourse/components/input-tip.js.es6
index aceafa7458..28e73eb0a2 100644
--- a/app/assets/javascripts/discourse/components/input-tip.js.es6
+++ b/app/assets/javascripts/discourse/components/input-tip.js.es6
@@ -1,13 +1,15 @@
+import { alias, not } from "@ember/object/computed";
+import Component from "@ember/component";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import { iconHTML } from "discourse-common/lib/icon-library";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
classNameBindings: [":tip", "good", "bad"],
rerenderTriggers: ["validation"],
- bad: Ember.computed.alias("validation.failed"),
- good: Ember.computed.not("bad"),
+ bad: alias("validation.failed"),
+ good: not("bad"),
buildBuffer(buffer) {
const reason = this.get("validation.reason");
diff --git a/app/assets/javascripts/discourse/components/invite-panel.js.es6 b/app/assets/javascripts/discourse/components/invite-panel.js.es6
index 432a0b7325..b1743d4f99 100644
--- a/app/assets/javascripts/discourse/components/invite-panel.js.es6
+++ b/app/assets/javascripts/discourse/components/invite-panel.js.es6
@@ -1,14 +1,18 @@
+import { isEmpty } from "@ember/utils";
+import { alias, and, equal } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import Component from "@ember/component";
import { emailValid } from "discourse/lib/utilities";
import computed from "ember-addons/ember-computed-decorators";
import Group from "discourse/models/group";
import Invite from "discourse/models/invite";
import { i18n } from "discourse/lib/computed";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: null,
- inviteModel: Ember.computed.alias("panel.model.inviteModel"),
- userInvitedShow: Ember.computed.alias("panel.model.userInvitedShow"),
+ inviteModel: alias("panel.model.inviteModel"),
+ userInvitedShow: alias("panel.model.userInvitedShow"),
// If this isn't defined, it will proxy to the user topic on the preferences
// page which is wrong.
@@ -18,7 +22,7 @@ export default Ember.Component.extend({
inviteIcon: "envelope",
invitingExistingUserToTopic: false,
- isAdmin: Ember.computed.alias("currentUser.admin"),
+ isAdmin: alias("currentUser.admin"),
willDestroyElement() {
this._super(...arguments);
@@ -45,7 +49,7 @@ export default Ember.Component.extend({
can_invite_to
) {
if (saving) return true;
- if (Ember.isEmpty(emailOrUsername)) return true;
+ if (isEmpty(emailOrUsername)) return true;
const emailTrimmed = emailOrUsername.trim();
@@ -60,11 +64,7 @@ export default Ember.Component.extend({
}
// when inviting to private topic via email, group name must be specified
- if (
- isPrivateTopic &&
- Ember.isEmpty(groupNames) &&
- emailValid(emailTrimmed)
- ) {
+ if (isPrivateTopic && isEmpty(groupNames) && emailValid(emailTrimmed)) {
return true;
}
@@ -91,7 +91,7 @@ export default Ember.Component.extend({
) {
if (hasCustomMessage) return true;
if (saving) return true;
- if (Ember.isEmpty(emailOrUsername)) return true;
+ if (isEmpty(emailOrUsername)) return true;
const email = emailOrUsername.trim();
@@ -106,7 +106,7 @@ export default Ember.Component.extend({
}
// when inviting to private topic via email, group name must be specified
- if (isPrivateTopic && Ember.isEmpty(groupNames) && emailValid(email)) {
+ if (isPrivateTopic && isEmpty(groupNames) && emailValid(email)) {
return true;
}
@@ -135,18 +135,18 @@ export default Ember.Component.extend({
return canInviteViaEmail && !isPM;
},
- topicId: Ember.computed.alias("inviteModel.id"),
+ topicId: alias("inviteModel.id"),
// eg: visible only to specific group members
- isPrivateTopic: Ember.computed.and(
+ isPrivateTopic: and(
"invitingToTopic",
"inviteModel.category.read_restricted"
),
- isPM: Ember.computed.equal("inviteModel.archetype", "private_message"),
+ isPM: equal("inviteModel.archetype", "private_message"),
// scope to allowed usernames
- allowExistingMembers: Ember.computed.alias("invitingToTopic"),
+ allowExistingMembers: alias("invitingToTopic"),
@computed("isAdmin", "inviteModel.group_users")
isGroupOwnerOrAdmin(isAdmin, groupUsers) {
@@ -215,7 +215,7 @@ export default Ember.Component.extend({
return I18n.t("topic.invite_reply.to_username");
} else {
// when inviting to a topic, display instructions based on provided entity
- if (Ember.isEmpty(emailOrUsername)) {
+ if (isEmpty(emailOrUsername)) {
return I18n.t("topic.invite_reply.to_topic_blank");
} else if (emailValid(emailOrUsername)) {
this.set("inviteIcon", "envelope");
@@ -323,7 +323,7 @@ export default Ember.Component.extend({
.then(data => {
model.setProperties({ saving: false, finished: true });
this.get("inviteModel.details.allowed_groups").pushObject(
- Ember.Object.create(data.group)
+ EmberObject.create(data.group)
);
this.appEvents.trigger("post-stream:refresh");
})
@@ -349,7 +349,7 @@ export default Ember.Component.extend({
});
} else if (this.isPM && result && result.user) {
this.get("inviteModel.details.allowed_users").pushObject(
- Ember.Object.create(result.user)
+ EmberObject.create(result.user)
);
this.appEvents.trigger("post-stream:refresh");
} else if (
diff --git a/app/assets/javascripts/discourse/components/latest-topic-list-item.js.es6 b/app/assets/javascripts/discourse/components/latest-topic-list-item.js.es6
index 487ae8aa46..f0e3ee875c 100644
--- a/app/assets/javascripts/discourse/components/latest-topic-list-item.js.es6
+++ b/app/assets/javascripts/discourse/components/latest-topic-list-item.js.es6
@@ -1,9 +1,10 @@
+import Component from "@ember/component";
import {
showEntrance,
navigateToTopic
} from "discourse/components/topic-list-item";
-export default Ember.Component.extend({
+export default Component.extend({
attributeBindings: ["topic.id:data-topic-id"],
classNameBindings: [
":latest-topic-list-item",
diff --git a/app/assets/javascripts/discourse/components/link-to-input.js.es6 b/app/assets/javascripts/discourse/components/link-to-input.js.es6
index 0afdbd304b..19015ec0e8 100644
--- a/app/assets/javascripts/discourse/components/link-to-input.js.es6
+++ b/app/assets/javascripts/discourse/components/link-to-input.js.es6
@@ -1,10 +1,12 @@
-export default Ember.Component.extend({
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
+export default Component.extend({
showInput: false,
click() {
this.onClick();
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(this.element)
.find("input")
.focus();
diff --git a/app/assets/javascripts/discourse/components/links-redirect.js.es6 b/app/assets/javascripts/discourse/components/links-redirect.js.es6
index 84d5f890f0..0ddd92b21b 100644
--- a/app/assets/javascripts/discourse/components/links-redirect.js.es6
+++ b/app/assets/javascripts/discourse/components/links-redirect.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import ClickTrack from "discourse/lib/click-track";
-export default Ember.Component.extend({
+export default Component.extend({
didInsertElement() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/components/load-more.js.es6 b/app/assets/javascripts/discourse/components/load-more.js.es6
index f81b33b764..8668fa5742 100644
--- a/app/assets/javascripts/discourse/components/load-more.js.es6
+++ b/app/assets/javascripts/discourse/components/load-more.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import LoadMore from "discourse/mixins/load-more";
-export default Ember.Component.extend(LoadMore, {
+export default Component.extend(LoadMore, {
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/components/login-buttons.js.es6 b/app/assets/javascripts/discourse/components/login-buttons.js.es6
index 3279bda5cc..a5a0967411 100644
--- a/app/assets/javascripts/discourse/components/login-buttons.js.es6
+++ b/app/assets/javascripts/discourse/components/login-buttons.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { findAll } from "discourse/models/login-method";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
elementId: "login-buttons",
classNameBindings: ["hidden"],
diff --git a/app/assets/javascripts/discourse/components/login-modal.js.es6 b/app/assets/javascripts/discourse/components/login-modal.js.es6
index 59939542cb..2ee72f8722 100644
--- a/app/assets/javascripts/discourse/components/login-modal.js.es6
+++ b/app/assets/javascripts/discourse/components/login-modal.js.es6
@@ -1,4 +1,6 @@
-export default Ember.Component.extend({
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
+export default Component.extend({
didInsertElement() {
this._super(...arguments);
@@ -13,7 +15,7 @@ export default Ember.Component.extend({
this.set("loginName", $.cookie("email"));
}
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$(
"#login-account-password, #login-account-name, #login-second-factor"
).keydown(e => {
diff --git a/app/assets/javascripts/discourse/components/mobile-category-topic.js.es6 b/app/assets/javascripts/discourse/components/mobile-category-topic.js.es6
index 4c47f0e126..fcd85640e6 100644
--- a/app/assets/javascripts/discourse/components/mobile-category-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/mobile-category-topic.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { showEntrance } from "discourse/components/topic-list-item";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "tr",
classNameBindings: [
":category-topic-link",
diff --git a/app/assets/javascripts/discourse/components/mobile-nav.js.es6 b/app/assets/javascripts/discourse/components/mobile-nav.js.es6
index 49392fc336..a47c09c5c4 100644
--- a/app/assets/javascripts/discourse/components/mobile-nav.js.es6
+++ b/app/assets/javascripts/discourse/components/mobile-nav.js.es6
@@ -1,6 +1,8 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import { on, observes } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
@on("init")
_init() {
if (!this.get("site.mobileView")) {
@@ -20,7 +22,7 @@ export default Ember.Component.extend({
@observes("currentPath")
currentPathChanged() {
this.set("expanded", false);
- Ember.run.next(() => this._updateSelectedHtml());
+ next(() => this._updateSelectedHtml());
},
_updateSelectedHtml() {
@@ -40,7 +42,7 @@ export default Ember.Component.extend({
toggleExpanded() {
this.toggleProperty("expanded");
- Ember.run.next(() => {
+ next(() => {
if (this.expanded) {
$(window)
.off("click.mobile-nav")
diff --git a/app/assets/javascripts/discourse/components/modal-panel.js.es6 b/app/assets/javascripts/discourse/components/modal-panel.js.es6
index b441457a7d..254dd32b73 100644
--- a/app/assets/javascripts/discourse/components/modal-panel.js.es6
+++ b/app/assets/javascripts/discourse/components/modal-panel.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { fmt } from "discourse/lib/computed";
-export default Ember.Component.extend({
+export default Component.extend({
panel: null,
panelComponent: fmt("panel.id", "%@-panel"),
diff --git a/app/assets/javascripts/discourse/components/modal-tab.js.es6 b/app/assets/javascripts/discourse/components/modal-tab.js.es6
index c7a392507c..94ff00ef9d 100644
--- a/app/assets/javascripts/discourse/components/modal-tab.js.es6
+++ b/app/assets/javascripts/discourse/components/modal-tab.js.es6
@@ -1,14 +1,16 @@
+import { equal, alias } from "@ember/object/computed";
+import Component from "@ember/component";
import { propertyEqual } from "discourse/lib/computed";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "li",
classNames: ["modal-tab"],
panel: null,
selectedPanel: null,
panelsLength: null,
classNameBindings: ["isActive", "singleTab", "panel.id"],
- singleTab: Ember.computed.equal("panelsLength", 1),
- title: Ember.computed.alias("panel.title"),
+ singleTab: equal("panelsLength", 1),
+ title: alias("panel.title"),
isActive: propertyEqual("panel.id", "selectedPanel.id"),
click() {
diff --git a/app/assets/javascripts/discourse/components/mount-widget.js.es6 b/app/assets/javascripts/discourse/components/mount-widget.js.es6
index d8431f2820..e62b7acab3 100644
--- a/app/assets/javascripts/discourse/components/mount-widget.js.es6
+++ b/app/assets/javascripts/discourse/components/mount-widget.js.es6
@@ -1,8 +1,12 @@
+import { cancel } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import { diff, patch } from "virtual-dom";
import { WidgetClickHook } from "discourse/widgets/hooks";
import { queryRegistry } from "discourse/widgets/widget";
import { getRegister } from "discourse-common/lib/get-owner";
import DirtyKeys from "discourse/lib/dirty-keys";
+import { camelize } from "@ember/string";
let _cleanCallbacks = {};
export function addWidgetCleanCallback(widgetName, fn) {
@@ -14,7 +18,7 @@ export function resetWidgetCleanCallbacks() {
_cleanCallbacks = {};
}
-export default Ember.Component.extend({
+export default Component.extend({
_tree: null,
_rootNode: null,
_timeout: null,
@@ -49,7 +53,7 @@ export default Ember.Component.extend({
this._rootNode = document.createElement("div");
this.element.appendChild(this._rootNode);
- this._timeout = Ember.run.scheduleOnce("render", this, this.rerenderWidget);
+ this._timeout = scheduleOnce("render", this, this.rerenderWidget);
},
willClearRender() {
@@ -67,7 +71,7 @@ export default Ember.Component.extend({
const [eventName, caller] = evt;
this.appEvents.off(eventName, this, caller);
});
- Ember.run.cancel(this._timeout);
+ cancel(this._timeout);
},
afterRender() {},
@@ -77,7 +81,7 @@ export default Ember.Component.extend({
afterPatch() {},
eventDispatched(eventName, key, refreshArg) {
- const onRefresh = Ember.String.camelize(eventName.replace(/:/, "-"));
+ const onRefresh = camelize(eventName.replace(/:/, "-"));
this.dirtyKeys.keyDirty(key, { onRefresh, refreshArg });
this.queueRerender();
},
@@ -96,13 +100,13 @@ export default Ember.Component.extend({
this._renderCallback = callback;
}
- Ember.run.scheduleOnce("render", this, this.rerenderWidget);
+ scheduleOnce("render", this, this.rerenderWidget);
},
buildArgs() {},
rerenderWidget() {
- Ember.run.cancel(this._timeout);
+ cancel(this._timeout);
if (this._rootNode) {
if (!this._widgetClass) {
diff --git a/app/assets/javascripts/discourse/components/nav-item.js.es6 b/app/assets/javascripts/discourse/components/nav-item.js.es6
index 2cff295403..d648e892d3 100644
--- a/app/assets/javascripts/discourse/components/nav-item.js.es6
+++ b/app/assets/javascripts/discourse/components/nav-item.js.es6
@@ -1,11 +1,13 @@
+import { inject as service } from "@ember/service";
+import Component from "@ember/component";
/* You might be looking for navigation-item. */
import { iconHTML } from "discourse-common/lib/icon-library";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "li",
classNameBindings: ["active"],
- router: Ember.inject.service(),
+ router: service(),
@computed("label", "i18nLabel", "icon")
contents(label, i18nLabel, icon) {
diff --git a/app/assets/javascripts/discourse/components/navigation-bar.js.es6 b/app/assets/javascripts/discourse/components/navigation-bar.js.es6
index 4be9c2c055..eb8cb454b3 100644
--- a/app/assets/javascripts/discourse/components/navigation-bar.js.es6
+++ b/app/assets/javascripts/discourse/components/navigation-bar.js.es6
@@ -1,3 +1,5 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes
@@ -5,7 +7,7 @@ import {
import DiscourseURL from "discourse/lib/url";
import { renderedConnectorsFor } from "discourse/lib/plugin-connectors";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "ul",
classNameBindings: [":nav", ":nav-pills"],
elementId: "navigation-bar",
@@ -20,9 +22,11 @@ export default Ember.Component.extend({
if (filterMode.indexOf("top/") === 0) {
filterMode = "top";
}
- var item = navItems.find(
- i => i.get("filterMode").indexOf(filterMode) === 0
- );
+ let item = navItems.find(i => i.active === true);
+
+ item =
+ item || navItems.find(i => i.get("filterMode").indexOf(filterMode) === 0);
+
if (!item) {
let connectors = this.connectors;
let category = this.category;
@@ -68,7 +72,7 @@ export default Ember.Component.extend({
if (this.expanded) {
DiscourseURL.appEvents.on("dom:clean", this, this.ensureDropClosed);
- Ember.run.next(() => {
+ next(() => {
if (!this.expanded) {
return;
}
@@ -76,7 +80,7 @@ export default Ember.Component.extend({
$(this.element.querySelector(".drop a")).on("click", () => {
this.element.querySelector(".drop").style.display = "none";
- Ember.run.next(() => {
+ next(() => {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
diff --git a/app/assets/javascripts/discourse/components/navigation-item.js.es6 b/app/assets/javascripts/discourse/components/navigation-item.js.es6
index 10290334a7..6d55112a94 100644
--- a/app/assets/javascripts/discourse/components/navigation-item.js.es6
+++ b/app/assets/javascripts/discourse/components/navigation-item.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { bufferedRender } from "discourse-common/lib/buffered-render";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
tagName: "li",
classNameBindings: [
@@ -14,8 +15,11 @@ export default Ember.Component.extend(
hidden: false,
rerenderTriggers: ["content.count"],
- @computed("content.filterMode", "filterMode")
- active(contentFilterMode, filterMode) {
+ @computed("content.filterMode", "filterMode", "content.active")
+ active(contentFilterMode, filterMode, active) {
+ if (active !== undefined) {
+ return active;
+ }
return (
contentFilterMode === filterMode ||
filterMode.indexOf(contentFilterMode) === 0
diff --git a/app/assets/javascripts/discourse/components/plugin-connector.js.es6 b/app/assets/javascripts/discourse/components/plugin-connector.js.es6
index 76590147ce..715cb62965 100644
--- a/app/assets/javascripts/discourse/components/plugin-connector.js.es6
+++ b/app/assets/javascripts/discourse/components/plugin-connector.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { observes } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/components/plugin-outlet.js.es6 b/app/assets/javascripts/discourse/components/plugin-outlet.js.es6
index 36b8929157..14e3805964 100644
--- a/app/assets/javascripts/discourse/components/plugin-outlet.js.es6
+++ b/app/assets/javascripts/discourse/components/plugin-outlet.js.es6
@@ -1,3 +1,4 @@
+import Component from "@ember/component";
/**
A plugin outlet is an extension point for templates where other templates can
be inserted by plugins.
@@ -31,7 +32,7 @@
**/
import { renderedConnectorsFor } from "discourse/lib/plugin-connectors";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "span",
connectors: null,
diff --git a/app/assets/javascripts/discourse/components/popup-input-tip.js.es6 b/app/assets/javascripts/discourse/components/popup-input-tip.js.es6
index 5f4fda605c..38930d57e4 100644
--- a/app/assets/javascripts/discourse/components/popup-input-tip.js.es6
+++ b/app/assets/javascripts/discourse/components/popup-input-tip.js.es6
@@ -1,3 +1,5 @@
+import { alias, not } from "@ember/object/computed";
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import {
default as computed,
@@ -5,7 +7,7 @@ import {
} from "ember-addons/ember-computed-decorators";
import { bufferedRender } from "discourse-common/lib/buffered-render";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
classNameBindings: [":popup-tip", "good", "bad", "lastShownAt::hide"],
animateAttribute: null,
@@ -18,8 +20,8 @@ export default Ember.Component.extend(
this.set("validation.lastShownAt", null);
},
- bad: Ember.computed.alias("validation.failed"),
- good: Ember.computed.not("bad"),
+ bad: alias("validation.failed"),
+ good: not("bad"),
@computed("shownAt", "validation.lastShownAt")
lastShownAt(shownAt, lastShownAt) {
diff --git a/app/assets/javascripts/discourse/components/preference-checkbox.js.es6 b/app/assets/javascripts/discourse/components/preference-checkbox.js.es6
index b0e84c117d..7ae299f5de 100644
--- a/app/assets/javascripts/discourse/components/preference-checkbox.js.es6
+++ b/app/assets/javascripts/discourse/components/preference-checkbox.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["controls"],
@computed("labelKey")
diff --git a/app/assets/javascripts/discourse/components/pwa-install-banner.js.es6 b/app/assets/javascripts/discourse/components/pwa-install-banner.js.es6
index 458fa3cebd..e2e60f3d88 100644
--- a/app/assets/javascripts/discourse/components/pwa-install-banner.js.es6
+++ b/app/assets/javascripts/discourse/components/pwa-install-banner.js.es6
@@ -1,3 +1,5 @@
+import { bind } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
on
@@ -5,7 +7,7 @@ import {
const USER_DISMISSED_PROMPT_KEY = "dismissed-pwa-install-banner";
-export default Ember.Component.extend({
+export default Component.extend({
deferredInstallPromptEvent: null,
_handleInstallPromptEvent(event) {
@@ -17,10 +19,7 @@ export default Ember.Component.extend({
@on("didInsertElement")
_registerListener() {
- this._promptEventHandler = Ember.run.bind(
- this,
- this._handleInstallPromptEvent
- );
+ this._promptEventHandler = bind(this, this._handleInstallPromptEvent);
window.addEventListener("beforeinstallprompt", this._promptEventHandler);
},
diff --git a/app/assets/javascripts/discourse/components/quote-button.js.es6 b/app/assets/javascripts/discourse/components/quote-button.js.es6
index 0bde5b4ffa..ec8b8c47e8 100644
--- a/app/assets/javascripts/discourse/components/quote-button.js.es6
+++ b/app/assets/javascripts/discourse/components/quote-button.js.es6
@@ -1,7 +1,9 @@
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import debounce from "discourse/lib/debounce";
import { selectedText } from "discourse/lib/utilities";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["quote-button"],
classNameBindings: ["visible"],
visible: false,
@@ -102,15 +104,18 @@ export default Ember.Component.extend({
}
// change the position of the button
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
let top = markerOffset.top;
let left = markerOffset.left + Math.max(0, parentScrollLeft);
if (showAtEnd) {
- top = top + 20;
+ const nearRightEdgeOfScreen =
+ $(window).width() - $quoteButton.outerWidth() < left + 10;
+
+ top = nearRightEdgeOfScreen ? top + 50 : top + 20;
left = Math.min(
left + 10,
- $(window).width() - $quoteButton.outerWidth()
+ $(window).width() - $quoteButton.outerWidth() - 10
);
} else {
top = top - $quoteButton.outerHeight() - 5;
diff --git a/app/assets/javascripts/discourse/components/radio-button.js.es6 b/app/assets/javascripts/discourse/components/radio-button.js.es6
index 4a7929d058..b6d44b4a99 100644
--- a/app/assets/javascripts/discourse/components/radio-button.js.es6
+++ b/app/assets/javascripts/discourse/components/radio-button.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "input",
type: "radio",
attributeBindings: [
@@ -13,10 +14,15 @@ export default Ember.Component.extend({
click() {
const value = $(this.element).val();
- if (this.selection === value) {
- this.set("selection", undefined);
+
+ if (this.onChange) {
+ this.onChange(value);
+ } else {
+ if (this.selection === value) {
+ this.set("selection", undefined);
+ }
+ this.set("selection", value);
}
- this.set("selection", value);
},
@computed("value", "selection")
diff --git a/app/assets/javascripts/discourse/components/related-messages.js.es6 b/app/assets/javascripts/discourse/components/related-messages.js.es6
index e7d65a4591..bf95279941 100644
--- a/app/assets/javascripts/discourse/components/related-messages.js.es6
+++ b/app/assets/javascripts/discourse/components/related-messages.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { iconHTML } from "discourse-common/lib/icon-library";
-export default Ember.Component.extend({
+export default Component.extend({
elementId: "related-messages",
classNames: ["suggested-topics"],
diff --git a/app/assets/javascripts/discourse/components/reviewable-bundled-action.js.es6 b/app/assets/javascripts/discourse/components/reviewable-bundled-action.js.es6
index d42a2dd290..2b3cc0fdf4 100644
--- a/app/assets/javascripts/discourse/components/reviewable-bundled-action.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-bundled-action.js.es6
@@ -1,8 +1,10 @@
-export default Ember.Component.extend({
+import { gt, alias } from "@ember/object/computed";
+import Component from "@ember/component";
+export default Component.extend({
tagName: "",
- multiple: Ember.computed.gt("bundle.actions.length", 1),
- first: Ember.computed.alias("bundle.actions.firstObject"),
+ multiple: gt("bundle.actions.length", 1),
+ first: alias("bundle.actions.firstObject"),
actions: {
performById(id) {
diff --git a/app/assets/javascripts/discourse/components/reviewable-claimed-topic.js.es6 b/app/assets/javascripts/discourse/components/reviewable-claimed-topic.js.es6
index d73a32d304..0583a4605f 100644
--- a/app/assets/javascripts/discourse/components/reviewable-claimed-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-claimed-topic.js.es6
@@ -1,8 +1,9 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
@computed
diff --git a/app/assets/javascripts/discourse/components/reviewable-conversation-post.js.es6 b/app/assets/javascripts/discourse/components/reviewable-conversation-post.js.es6
index b57e6aa5de..9fc360d10c 100644
--- a/app/assets/javascripts/discourse/components/reviewable-conversation-post.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-conversation-post.js.es6
@@ -1,3 +1,5 @@
-export default Ember.Component.extend({
- showUsername: Ember.computed.gte("index", 1)
+import { gte } from "@ember/object/computed";
+import Component from "@ember/component";
+export default Component.extend({
+ showUsername: gte("index", 1)
});
diff --git a/app/assets/javascripts/discourse/components/reviewable-flagged-post.js.es6 b/app/assets/javascripts/discourse/components/reviewable-flagged-post.js.es6
index 1916a96125..58c48d1bbf 100644
--- a/app/assets/javascripts/discourse/components/reviewable-flagged-post.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-flagged-post.js.es6
@@ -1,10 +1,12 @@
+import { gt } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { longDate } from "discourse/lib/formatter";
import { historyHeat } from "discourse/widgets/post-edits-indicator";
import showModal from "discourse/lib/show-modal";
-export default Ember.Component.extend({
- hasEdits: Ember.computed.gt("reviewable.post_version", 1),
+export default Component.extend({
+ hasEdits: gt("reviewable.post_version", 1),
@computed("reviewable.post_updated_at")
historyClass(updatedAt) {
diff --git a/app/assets/javascripts/discourse/components/reviewable-histories.js.es6 b/app/assets/javascripts/discourse/components/reviewable-histories.js.es6
index a5f1a7932e..f52c1c4000 100644
--- a/app/assets/javascripts/discourse/components/reviewable-histories.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-histories.js.es6
@@ -1,3 +1,5 @@
-export default Ember.Component.extend({
- filteredHistories: Ember.computed.filterBy("histories", "created", false)
+import { filterBy } from "@ember/object/computed";
+import Component from "@ember/component";
+export default Component.extend({
+ filteredHistories: filterBy("histories", "created", false)
});
diff --git a/app/assets/javascripts/discourse/components/reviewable-item.js.es6 b/app/assets/javascripts/discourse/components/reviewable-item.js.es6
index 4507704d95..c5aaba8b7b 100644
--- a/app/assets/javascripts/discourse/components/reviewable-item.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-item.js.es6
@@ -1,13 +1,16 @@
+import Component from "@ember/component";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
import Category from "discourse/models/category";
import optionalService from "discourse/lib/optional-service";
import showModal from "discourse/lib/show-modal";
+import { dasherize } from "@ember/string";
+import { set } from "@ember/object";
let _components = {};
-export default Ember.Component.extend({
+export default Component.extend({
adminTools: optionalService(),
tagName: "",
updating: null,
@@ -64,7 +67,7 @@ export default Ember.Component.extend({
return _components[type];
}
- let dasherized = Ember.String.dasherize(type);
+ let dasherized = dasherize(type);
let templatePath = `components/${dasherized}`;
let template =
Ember.TEMPLATES[`${templatePath}`] ||
@@ -184,7 +187,7 @@ export default Ember.Component.extend({
},
valueChanged(fieldId, event) {
- Ember.set(this._updates, fieldId, event.target.value);
+ set(this._updates, fieldId, event.target.value);
},
perform(action) {
diff --git a/app/assets/javascripts/discourse/components/reviewable-queued-post.js.es6 b/app/assets/javascripts/discourse/components/reviewable-queued-post.js.es6
index 1255c5bddc..2e17ce9423 100644
--- a/app/assets/javascripts/discourse/components/reviewable-queued-post.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-queued-post.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import showModal from "discourse/lib/show-modal";
-export default Ember.Component.extend({
+export default Component.extend({
actions: {
showRawEmail() {
showModal("raw-email").set("rawEmail", this.reviewable.payload.raw_email);
diff --git a/app/assets/javascripts/discourse/components/reviewable-user.js.es6 b/app/assets/javascripts/discourse/components/reviewable-user.js.es6
index f071ba7b33..ec065a0bde 100644
--- a/app/assets/javascripts/discourse/components/reviewable-user.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-user.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("reviewable.user_fields")
userFields(fields) {
return this.site.collectUserFields(fields);
diff --git a/app/assets/javascripts/discourse/components/scroll-tracker.js.es6 b/app/assets/javascripts/discourse/components/scroll-tracker.js.es6
index caad7dc87a..7637845c1e 100644
--- a/app/assets/javascripts/discourse/components/scroll-tracker.js.es6
+++ b/app/assets/javascripts/discourse/components/scroll-tracker.js.es6
@@ -1,6 +1,8 @@
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
import Scrolling from "discourse/mixins/scrolling";
-export default Ember.Component.extend(Scrolling, {
+export default Component.extend(Scrolling, {
didReceiveAttrs() {
this._super(...arguments);
@@ -18,7 +20,7 @@ export default Ember.Component.extend(Scrolling, {
const data = this.session.get(this.trackerName);
if (data && data.position >= 0 && data.tag === this.tag) {
- Ember.run.next(() => $(window).scrollTop(data.position + 1));
+ next(() => $(window).scrollTop(data.position + 1));
}
},
diff --git a/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 b/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6
index 89a48126f3..04f0897eb6 100644
--- a/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6
+++ b/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6
@@ -1,3 +1,6 @@
+import { next } from "@ember/runloop";
+import { debounce } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
import DiscourseURL from "discourse/lib/url";
import MountWidget from "discourse/components/mount-widget";
import { cloak, uncloak } from "discourse/widgets/post-stream";
@@ -204,7 +207,7 @@ export default MountWidget.extend({
// will cause the browser to scroll to the top of the document
// in Chrome. This makes sure the scroll works correctly if that
// happens.
- Ember.run.next(() => $("html, body").scrollTop(whereY));
+ next(() => $("html, body").scrollTop(whereY));
}
});
};
@@ -270,7 +273,7 @@ export default MountWidget.extend({
},
_scrollTriggered() {
- Ember.run.scheduleOnce("afterRender", this, this.scrolled);
+ scheduleOnce("afterRender", this, this.scrolled);
},
_posted(staged) {
@@ -306,13 +309,12 @@ export default MountWidget.extend({
},
_debouncedScroll() {
- Ember.run.debounce(this, this._scrollTriggered, 10);
+ debounce(this, this._scrollTriggered, 10);
},
didInsertElement() {
this._super(...arguments);
- const debouncedScroll = () =>
- Ember.run.debounce(this, this._scrollTriggered, 10);
+ const debouncedScroll = () => debounce(this, this._scrollTriggered, 10);
this._previouslyNearby = {};
diff --git a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6 b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6
index 50da93e6c2..8f1779487d 100644
--- a/app/assets/javascripts/discourse/components/search-advanced-options.js.es6
+++ b/app/assets/javascripts/discourse/components/search-advanced-options.js.es6
@@ -1,3 +1,6 @@
+import { debounce } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import { observes } from "ember-addons/ember-computed-decorators";
import { escapeExpression } from "discourse/lib/utilities";
import Group from "discourse/models/group";
@@ -28,7 +31,7 @@ const REGEXP_POST_TIME_WHEN = /^(before|after)/gi;
const IN_OPTIONS_MAPPING = { images: "with" };
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["search-advanced-options"],
init() {
@@ -71,13 +74,13 @@ export default Ember.Component.extend({
this._init();
- Ember.run.scheduleOnce("afterRender", () => this._update());
+ scheduleOnce("afterRender", () => this._update());
},
@observes("searchTerm")
_updateOptions() {
this._update();
- Ember.run.debounce(this, this._update, 250);
+ debounce(this, this._update, 250);
},
_init() {
diff --git a/app/assets/javascripts/discourse/components/second-factor-form.js.es6 b/app/assets/javascripts/discourse/components/second-factor-form.js.es6
index 572fd509f7..ce332c23b1 100644
--- a/app/assets/javascripts/discourse/components/second-factor-form.js.es6
+++ b/app/assets/javascripts/discourse/components/second-factor-form.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("secondFactorMethod")
secondFactorTitle(secondFactorMethod) {
switch (secondFactorMethod) {
diff --git a/app/assets/javascripts/discourse/components/second-factor-input.js.es6 b/app/assets/javascripts/discourse/components/second-factor-input.js.es6
index 00e27039a4..97ce1a4fa7 100644
--- a/app/assets/javascripts/discourse/components/second-factor-input.js.es6
+++ b/app/assets/javascripts/discourse/components/second-factor-input.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
-export default Ember.Component.extend({
+export default Component.extend({
@computed("secondFactorMethod")
type(secondFactorMethod) {
if (secondFactorMethod === SECOND_FACTOR_METHODS.TOTP) return "tel";
diff --git a/app/assets/javascripts/discourse/components/security-key-form.js.es6 b/app/assets/javascripts/discourse/components/security-key-form.js.es6
index 3161831869..d315bf6889 100644
--- a/app/assets/javascripts/discourse/components/security-key-form.js.es6
+++ b/app/assets/javascripts/discourse/components/security-key-form.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
-export default Ember.Component.extend({
+export default Component.extend({
actions: {
useAnotherMethod() {
this.set("showSecurityKey", false);
diff --git a/app/assets/javascripts/discourse/components/share-panel.js.es6 b/app/assets/javascripts/discourse/components/share-panel.js.es6
index 136e6a9ccc..3a7b94b645 100644
--- a/app/assets/javascripts/discourse/components/share-panel.js.es6
+++ b/app/assets/javascripts/discourse/components/share-panel.js.es6
@@ -1,13 +1,17 @@
+import { isEmpty } from "@ember/utils";
+import { alias } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import { escapeExpression } from "discourse/lib/utilities";
import { default as computed } from "ember-addons/ember-computed-decorators";
import Sharing from "discourse/lib/sharing";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: null,
- type: Ember.computed.alias("panel.model.type"),
+ type: alias("panel.model.type"),
- topic: Ember.computed.alias("panel.model.topic"),
+ topic: alias("panel.model.topic"),
@computed
sources() {
@@ -24,7 +28,7 @@ export default Ember.Component.extend({
shareUrl(forcedShareUrl, shareUrl) {
shareUrl = forcedShareUrl || shareUrl;
- if (Ember.isEmpty(shareUrl)) {
+ if (isEmpty(shareUrl)) {
return;
}
@@ -46,7 +50,7 @@ export default Ember.Component.extend({
this.element.querySelector(".topic-share-url-for-touch a")
);
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
if (!this.capabilities.touch) {
$linkForTouch.parent().remove();
diff --git a/app/assets/javascripts/discourse/components/share-popup.js.es6 b/app/assets/javascripts/discourse/components/share-popup.js.es6
index dad5d68949..4f9d0b9792 100644
--- a/app/assets/javascripts/discourse/components/share-popup.js.es6
+++ b/app/assets/javascripts/discourse/components/share-popup.js.es6
@@ -1,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import { bind } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import { wantsNewWindow } from "discourse/lib/intercept-click";
import { longDateNoYear } from "discourse/lib/formatter";
import {
@@ -7,7 +11,7 @@ import {
import Sharing from "discourse/lib/sharing";
import { nativeShare } from "discourse/lib/pwa-utils";
-export default Ember.Component.extend({
+export default Component.extend({
elementId: "share-link",
classNameBindings: ["visible"],
link: null,
@@ -56,7 +60,7 @@ export default Ember.Component.extend({
const $currentTargetOffset = $target.offset();
const $this = $(this.element);
- if (Ember.isEmpty(url)) {
+ if (isEmpty(url)) {
return;
}
@@ -85,10 +89,10 @@ export default Ember.Component.extend({
if (!this.site.mobileView) {
$this.css({ left: "" + x + "px" });
}
- this.set("link", encodeURI(url));
+ this.set("link", url);
this.set("visible", true);
- Ember.run.scheduleOnce("afterRender", this, this._focusUrl);
+ scheduleOnce("afterRender", this, this._focusUrl);
},
_mouseDownHandler(event) {
@@ -153,9 +157,9 @@ export default Ember.Component.extend({
@on("init")
_setupHandlers() {
- this._boundMouseDownHandler = Ember.run.bind(this, this._mouseDownHandler);
- this._boundClickHandler = Ember.run.bind(this, this._clickHandler);
- this._boundKeydownHandler = Ember.run.bind(this, this._keydownHandler);
+ this._boundMouseDownHandler = bind(this, this._mouseDownHandler);
+ this._boundClickHandler = bind(this, this._clickHandler);
+ this._boundKeydownHandler = bind(this, this._keydownHandler);
},
didInsertElement() {
diff --git a/app/assets/javascripts/discourse/components/share-source.js.es6 b/app/assets/javascripts/discourse/components/share-source.js.es6
index 0eb7020886..1ce8f6e5da 100644
--- a/app/assets/javascripts/discourse/components/share-source.js.es6
+++ b/app/assets/javascripts/discourse/components/share-source.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNameBindings: [":social-link"],
actions: {
diff --git a/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6 b/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6
index 002a13e7da..b408ee87a1 100644
--- a/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6
+++ b/app/assets/javascripts/discourse/components/shared-draft-controls.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
publishing: false,
diff --git a/app/assets/javascripts/discourse/components/signup-cta.js.es6 b/app/assets/javascripts/discourse/components/signup-cta.js.es6
index dbbc7ad1d5..7d6f1623e4 100644
--- a/app/assets/javascripts/discourse/components/signup-cta.js.es6
+++ b/app/assets/javascripts/discourse/components/signup-cta.js.es6
@@ -1,4 +1,8 @@
-export default Ember.Component.extend({
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
+import { on } from "@ember/object/evented";
+
+export default Component.extend({
action: "showCreateAccount",
actions: {
@@ -9,16 +13,13 @@ export default Ember.Component.extend({
hideForSession() {
this.session.set("hideSignupCta", true);
this.keyValueStore.setItem("anon-cta-hidden", new Date().getTime());
- Ember.run.later(
- () => this.session.set("showSignupCta", false),
- 20 * 1000
- );
+ later(() => this.session.set("showSignupCta", false), 20 * 1000);
}
},
- _turnOffIfHidden: function() {
+ _turnOffIfHidden: on("willDestroyElement", function() {
if (this.session.get("hideSignupCta")) {
this.session.set("showSignupCta", false);
}
- }.on("willDestroyElement")
+ })
});
diff --git a/app/assets/javascripts/discourse/components/site-header.js.es6 b/app/assets/javascripts/discourse/components/site-header.js.es6
index 41c71a48e5..b7b82071c1 100644
--- a/app/assets/javascripts/discourse/components/site-header.js.es6
+++ b/app/assets/javascripts/discourse/components/site-header.js.es6
@@ -1,3 +1,6 @@
+import { cancel } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
+import { later } from "@ember/runloop";
import MountWidget from "discourse/components/mount-widget";
import { observes } from "ember-addons/ember-computed-decorators";
import Docking from "discourse/mixins/docking";
@@ -38,7 +41,7 @@ const SiteHeaderComponent = MountWidget.extend(Docking, PanEvents, {
_animateClosing($panel, menuOrigin, windowWidth) {
$panel.css(menuOrigin, -windowWidth);
this._animate = true;
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
this.eventDispatched("dom:clean", "header");
this._panMenuOffset = 0;
});
@@ -222,7 +225,7 @@ const SiteHeaderComponent = MountWidget.extend(Docking, PanEvents, {
this.appEvents.off("header:hide-topic", this, "setTopic");
this.appEvents.off("dom:clean", this, "_cleanDom");
- Ember.run.cancel(this._scheduledRemoveAnimate);
+ cancel(this._scheduledRemoveAnimate);
window.cancelAnimationFrame(this._scheduledMovingAnimation);
},
@@ -346,7 +349,7 @@ const SiteHeaderComponent = MountWidget.extend(Docking, PanEvents, {
if (this._animate) {
$panel.addClass("animate");
$headerCloak.addClass("animate");
- this._scheduledRemoveAnimate = Ember.run.later(() => {
+ this._scheduledRemoveAnimate = later(() => {
$panel.removeClass("animate");
$headerCloak.removeClass("animate");
}, 200);
diff --git a/app/assets/javascripts/discourse/components/suggested-topics.js.es6 b/app/assets/javascripts/discourse/components/suggested-topics.js.es6
index b5756b859c..11b6cbf20d 100644
--- a/app/assets/javascripts/discourse/components/suggested-topics.js.es6
+++ b/app/assets/javascripts/discourse/components/suggested-topics.js.es6
@@ -1,8 +1,10 @@
+import { get } from "@ember/object";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { categoryBadgeHTML } from "discourse/helpers/category-link";
import { iconHTML } from "discourse-common/lib/icon-library";
-export default Ember.Component.extend({
+export default Component.extend({
elementId: "suggested-topics",
classNames: ["suggested-topics"],
@@ -34,7 +36,7 @@ export default Ember.Component.extend({
if (
category &&
- Ember.get(category, "id") ===
+ get(category, "id") ===
Discourse.Site.currentProp("uncategorized_category_id")
) {
category = null;
diff --git a/app/assets/javascripts/discourse/components/tag-drop-link.js.es6 b/app/assets/javascripts/discourse/components/tag-drop-link.js.es6
index ab41561429..73d20d7922 100644
--- a/app/assets/javascripts/discourse/components/tag-drop-link.js.es6
+++ b/app/assets/javascripts/discourse/components/tag-drop-link.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import DiscourseURL from "discourse/lib/url";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "a",
classNameBindings: [
":tag-badge-wrapper",
diff --git a/app/assets/javascripts/discourse/components/tag-groups-form.js.es6 b/app/assets/javascripts/discourse/components/tag-groups-form.js.es6
new file mode 100644
index 0000000000..2dddb086e8
--- /dev/null
+++ b/app/assets/javascripts/discourse/components/tag-groups-form.js.es6
@@ -0,0 +1,70 @@
+import { isEmpty } from "@ember/utils";
+import Component from "@ember/component";
+import computed from "ember-addons/ember-computed-decorators";
+import { bufferedProperty } from "discourse/mixins/buffered-content";
+import PermissionType from "discourse/models/permission-type";
+
+export default Component.extend(bufferedProperty("model"), {
+ tagName: "",
+
+ @computed("buffered.isSaving", "buffered.name", "buffered.tag_names")
+ savingDisabled(isSaving, name, tagNames) {
+ return isSaving || isEmpty(name) || isEmpty(tagNames);
+ },
+
+ actions: {
+ setPermissions(permissionName) {
+ if (permissionName === "private") {
+ this.buffered.set("permissions", {
+ staff: PermissionType.FULL
+ });
+ } else if (permissionName === "visible") {
+ this.buffered.set("permissions", {
+ staff: PermissionType.FULL,
+ everyone: PermissionType.READONLY
+ });
+ } else {
+ this.buffered.set("permissions", {
+ everyone: PermissionType.FULL
+ });
+ }
+ },
+
+ save() {
+ const attrs = this.buffered.getProperties(
+ "name",
+ "tag_names",
+ "parent_tag_name",
+ "one_per_topic",
+ "permissions"
+ );
+
+ this.model.save(attrs).then(() => {
+ this.commitBuffer();
+
+ if (this.onSave) {
+ this.onSave();
+ }
+ });
+ },
+
+ destroy() {
+ return bootbox.confirm(
+ I18n.t("tagging.groups.confirm_delete"),
+ I18n.t("no_value"),
+ I18n.t("yes_value"),
+ destroy => {
+ if (!destroy) {
+ return;
+ }
+
+ this.model.destroyRecord().then(() => {
+ if (this.onDestroy) {
+ this.onDestroy();
+ }
+ });
+ }
+ );
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/components/tag-list.js.es6 b/app/assets/javascripts/discourse/components/tag-list.js.es6
index a6578bb398..551b70c93d 100644
--- a/app/assets/javascripts/discourse/components/tag-list.js.es6
+++ b/app/assets/javascripts/discourse/components/tag-list.js.es6
@@ -1,10 +1,12 @@
+import { sort } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
- classNameBindings: [":tag-list", "categoryClass"],
+export default Component.extend({
+ classNameBindings: [":tag-list", "categoryClass", "tagGroupNameClass"],
isPrivateMessage: false,
- sortedTags: Ember.computed.sort("tags", "sortProperties"),
+ sortedTags: sort("tags", "sortProperties"),
@computed("titleKey")
title(titleKey) {
@@ -19,5 +21,16 @@ export default Ember.Component.extend({
@computed("category.fullSlug")
categoryClass(slug) {
return slug && `tag-list-${slug}`;
+ },
+
+ @computed("tagGroupName")
+ tagGroupNameClass(groupName) {
+ if (groupName) {
+ groupName = groupName
+ .replace(/\s+/g, "-")
+ .replace(/[!\"#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, "")
+ .toLowerCase();
+ return groupName && `tag-group-${groupName}`;
+ }
}
});
diff --git a/app/assets/javascripts/discourse/components/text-overflow.js.es6 b/app/assets/javascripts/discourse/components/text-overflow.js.es6
index a63b6fed5d..d5bc066fb0 100644
--- a/app/assets/javascripts/discourse/components/text-overflow.js.es6
+++ b/app/assets/javascripts/discourse/components/text-overflow.js.es6
@@ -1,7 +1,9 @@
-export default Ember.Component.extend({
+import { next } from "@ember/runloop";
+import Component from "@ember/component";
+export default Component.extend({
didInsertElement() {
this._super(...arguments);
- Ember.run.next(null, () => {
+ next(null, () => {
const $this = $(this.element);
if ($this) {
diff --git a/app/assets/javascripts/discourse/components/time-input.js.es6 b/app/assets/javascripts/discourse/components/time-input.js.es6
index bdeb1b3a72..e636380a77 100644
--- a/app/assets/javascripts/discourse/components/time-input.js.es6
+++ b/app/assets/javascripts/discourse/components/time-input.js.es6
@@ -1,14 +1,17 @@
+import { oneWay, or } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import { isNumeric } from "discourse/lib/utilities";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["d-time-input"],
hours: null,
minutes: null,
- _hours: Ember.computed.oneWay("hours"),
- _minutes: Ember.computed.oneWay("minutes"),
- isSafari: Ember.computed.oneWay("capabilities.isSafari"),
- isMobile: Ember.computed.oneWay("site.mobileView"),
- nativePicker: Ember.computed.or("isSafari", "isMobile"),
+ _hours: oneWay("hours"),
+ _minutes: oneWay("minutes"),
+ isSafari: oneWay("capabilities.isSafari"),
+ isMobile: oneWay("site.mobileView"),
+ nativePicker: or("isSafari", "isMobile"),
actions: {
onInput(options, event) {
@@ -35,7 +38,7 @@ export default Ember.Component.extend({
this._processMinutesChange(value);
}
- Ember.run.schedule("afterRender", () => (event.target.value = value));
+ schedule("afterRender", () => (event.target.value = value));
}
},
diff --git a/app/assets/javascripts/discourse/components/top-period-buttons.js.es6 b/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
index 059b1a1468..9c01cf1a1d 100644
--- a/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
+++ b/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["top-title-buttons"],
@computed("period")
diff --git a/app/assets/javascripts/discourse/components/topic-category.js.es6 b/app/assets/javascripts/discourse/components/topic-category.js.es6
index 97fcde13cd..3f003c8d77 100644
--- a/app/assets/javascripts/discourse/components/topic-category.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-category.js.es6
@@ -1,2 +1,3 @@
+import Component from "@ember/component";
// Injections don't occur without a class
-export default Ember.Component.extend();
+export default Component.extend();
diff --git a/app/assets/javascripts/discourse/components/topic-entrance.js.es6 b/app/assets/javascripts/discourse/components/topic-entrance.js.es6
index e90ccd5857..ead6913e82 100644
--- a/app/assets/javascripts/discourse/components/topic-entrance.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-entrance.js.es6
@@ -1,3 +1,5 @@
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import DiscourseURL from "discourse/lib/url";
import CleansUp from "discourse/mixins/cleans-up";
import computed from "ember-addons/ember-computed-decorators";
@@ -25,7 +27,7 @@ function entranceDate(dt, showTime) {
);
}
-export default Ember.Component.extend(CleansUp, {
+export default Component.extend(CleansUp, {
elementId: "topic-entrance",
classNameBindings: ["visible::hidden"],
_position: null,
@@ -76,7 +78,7 @@ export default Ember.Component.extend(CleansUp, {
this.setProperties({ topic: data.topic, visible: true });
- Ember.run.scheduleOnce("afterRender", this, this._setCSS);
+ scheduleOnce("afterRender", this, this._setCSS);
$("html")
.off("mousedown.topic-entrance")
diff --git a/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 b/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6
index 0c487e7353..7c13728bff 100644
--- a/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6
@@ -1,7 +1,9 @@
+import { alias, or, and } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { getTopicFooterButtons } from "discourse/lib/register-topic-footer-button";
-export default Ember.Component.extend({
+export default Component.extend({
elementId: "topic-footer-buttons",
// Allow us to extend it
@@ -30,15 +32,11 @@ export default Ember.Component.extend({
return !isPM || this.siteSettings.enable_personal_messages;
},
- canInviteTo: Ember.computed.alias("topic.details.can_invite_to"),
+ canInviteTo: alias("topic.details.can_invite_to"),
- canDefer: Ember.computed.alias("currentUser.enable_defer"),
+ canDefer: alias("currentUser.enable_defer"),
- inviteDisabled: Ember.computed.or(
- "topic.archived",
- "topic.closed",
- "topic.deleted"
- ),
+ inviteDisabled: or("topic.archived", "topic.closed", "topic.deleted"),
@computed
showAdminButton() {
@@ -49,10 +47,7 @@ export default Ember.Component.extend({
);
},
- showEditOnFooter: Ember.computed.and(
- "topic.isPrivateMessage",
- "site.can_tag_pms"
- ),
+ showEditOnFooter: and("topic.isPrivateMessage", "site.can_tag_pms"),
@computed("topic.message_archived")
archiveIcon: archived => (archived ? "envelope" : "folder"),
diff --git a/app/assets/javascripts/discourse/components/topic-join-group-notice.js.es6 b/app/assets/javascripts/discourse/components/topic-join-group-notice.js.es6
index 1fd4f9264d..114e02aa04 100644
--- a/app/assets/javascripts/discourse/components/topic-join-group-notice.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-join-group-notice.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
classNames: ["topic-notice"],
@computed("model.group.{full_name,name,allow_membership_requests}")
diff --git a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 b/app/assets/javascripts/discourse/components/topic-list-item.js.es6
index 1116d97e61..10161d7b51 100644
--- a/app/assets/javascripts/discourse/components/topic-list-item.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-list-item.js.es6
@@ -1,8 +1,11 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import DiscourseURL from "discourse/lib/url";
import computed from "ember-addons/ember-computed-decorators";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import { findRawTemplate } from "discourse/lib/raw-templates";
import { wantsNewWindow } from "discourse/lib/intercept-click";
+import { on } from "@ember/object/evented";
export function showEntrance(e) {
let target = $(e.target);
@@ -33,7 +36,7 @@ export const ListItemDefaults = {
tagName: "tr",
classNameBindings: [":topic-list-item", "unboundClassNames", "topic.visited"],
attributeBindings: ["data-topic-id"],
- "data-topic-id": Ember.computed.alias("topic.id"),
+ "data-topic-id": alias("topic.id"),
didInsertElement() {
this._super(...arguments);
@@ -202,7 +205,7 @@ export const ListItemDefaults = {
$topic.on("animationend", () => $topic.removeClass("highlighted"));
},
- _highlightIfNeeded: function() {
+ _highlightIfNeeded: on("didInsertElement", function() {
// highlight the last topic viewed
if (this.session.get("lastTopicIdViewed") === this.get("topic.id")) {
this.session.set("lastTopicIdViewed", null);
@@ -212,10 +215,10 @@ export const ListItemDefaults = {
this.set("topic.highlight", false);
this.highlight();
}
- }.on("didInsertElement")
+ })
};
-export default Ember.Component.extend(
+export default Component.extend(
ListItemDefaults,
bufferedRender({
rerenderTriggers: ["bulkSelectEnabled", "topic.pinned"],
diff --git a/app/assets/javascripts/discourse/components/topic-list.js.es6 b/app/assets/javascripts/discourse/components/topic-list.js.es6
index 44846d5b0d..6d3ea337e2 100644
--- a/app/assets/javascripts/discourse/components/topic-list.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-list.js.es6
@@ -1,23 +1,28 @@
+import { alias, reads } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
+import LoadMore from "discourse/mixins/load-more";
+import { on } from "@ember/object/evented";
-export default Ember.Component.extend({
+export default Component.extend(LoadMore, {
tagName: "table",
classNames: ["topic-list"],
showTopicPostBadges: true,
listTitle: "topic.title",
// Overwrite this to perform client side filtering of topics, if desired
- filteredTopics: Ember.computed.alias("topics"),
+ filteredTopics: alias("topics"),
- _init: function() {
+ _init: on("init", function() {
this.addObserver("hideCategory", this.rerender);
this.addObserver("order", this.rerender);
this.addObserver("ascending", this.rerender);
this.refreshLastVisited();
- }.on("init"),
+ }),
@computed("bulkSelectEnabled")
toggleInTitle(bulkSelectEnabled) {
@@ -29,7 +34,7 @@ export default Ember.Component.extend({
return !!this.changeSort;
},
- skipHeader: Ember.computed.reads("site.mobileView"),
+ skipHeader: reads("site.mobileView"),
@computed("order")
showLikes(order) {
@@ -54,6 +59,28 @@ export default Ember.Component.extend({
this.refreshLastVisited();
},
+ scrolled() {
+ this._super(...arguments);
+ let onScroll = this.onScroll;
+ if (!onScroll) return;
+
+ onScroll.call(this);
+ },
+
+ scrollToLastPosition() {
+ if (!this.scrollOnLoad) return;
+
+ let scrollTo = this.session.get("topicListScrollPosition");
+ if (scrollTo && scrollTo >= 0) {
+ schedule("afterRender", () => $(window).scrollTop(scrollTo + 1));
+ }
+ },
+
+ didInsertElement() {
+ this._super(...arguments);
+ this.scrollToLastPosition();
+ },
+
_updateLastVisitedTopic(topics, order, ascending, top) {
this.set("lastVisitedTopic", null);
diff --git a/app/assets/javascripts/discourse/components/topic-navigation.js.es6 b/app/assets/javascripts/discourse/components/topic-navigation.js.es6
index 28cf8b4ae7..b2115e755d 100644
--- a/app/assets/javascripts/discourse/components/topic-navigation.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-navigation.js.es6
@@ -1,3 +1,7 @@
+import EmberObject from "@ember/object";
+import { scheduleOnce } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
import { observes } from "ember-addons/ember-computed-decorators";
import showModal from "discourse/lib/show-modal";
import PanEvents, {
@@ -6,14 +10,14 @@ import PanEvents, {
SWIPE_VELOCITY_THRESHOLD
} from "discourse/mixins/pan-events";
-export default Ember.Component.extend(PanEvents, {
+export default Component.extend(PanEvents, {
composerOpen: null,
info: null,
isPanning: false,
init() {
this._super(...arguments);
- this.set("info", Ember.Object.create());
+ this.set("info", EmberObject.create());
},
_performCheckSize() {
@@ -50,7 +54,7 @@ export default Ember.Component.extend(PanEvents, {
},
_checkSize() {
- Ember.run.scheduleOnce("afterRender", this, this._performCheckSize);
+ scheduleOnce("afterRender", this, this._performCheckSize);
},
// we need to store this so topic progress has something to init with
@@ -86,7 +90,7 @@ export default Ember.Component.extend(PanEvents, {
composerOpened() {
this.set("composerOpen", true);
// we need to do the check after animation is done
- Ember.run.later(() => this._checkSize(), 500);
+ later(() => this._checkSize(), 500);
},
composerClosed() {
@@ -97,7 +101,7 @@ export default Ember.Component.extend(PanEvents, {
_collapseFullscreen() {
if (this.get("info.topicProgressExpanded")) {
$(".timeline-fullscreen").removeClass("show");
- Ember.run.later(() => {
+ later(() => {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
@@ -135,7 +139,7 @@ export default Ember.Component.extend(PanEvents, {
} else if (offset <= 0) {
$timelineContainer.css("bottom", "");
} else {
- Ember.run.later(() => this._handlePanDone(offset, event), 20);
+ later(() => this._handlePanDone(offset, event), 20);
}
},
diff --git a/app/assets/javascripts/discourse/components/topic-post-badges.js.es6 b/app/assets/javascripts/discourse/components/topic-post-badges.js.es6
index 69235be0ca..e6b70ab212 100644
--- a/app/assets/javascripts/discourse/components/topic-post-badges.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-post-badges.js.es6
@@ -1,3 +1,4 @@
+import Component from "@ember/component";
import { bufferedRender } from "discourse-common/lib/buffered-render";
// Creates a link
@@ -12,7 +13,7 @@ function link(buffer, prop, url, cssClass, i18nKey, text) {
);
}
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
tagName: "span",
classNameBindings: [":topic-post-badges"],
diff --git a/app/assets/javascripts/discourse/components/topic-progress.js.es6 b/app/assets/javascripts/discourse/components/topic-progress.js.es6
index e37d5821c2..9d5cb2103f 100644
--- a/app/assets/javascripts/discourse/components/topic-progress.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-progress.js.es6
@@ -1,14 +1,17 @@
+import { alias } from "@ember/object/computed";
+import { scheduleOnce } from "@ember/runloop";
+import Component from "@ember/component";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
elementId: "topic-progress-wrapper",
classNameBindings: ["docked"],
docked: false,
progressPosition: null,
- postStream: Ember.computed.alias("topic.postStream"),
+ postStream: alias("topic.postStream"),
_streamPercentage: null,
@computed("progressPosition")
@@ -72,7 +75,7 @@ export default Ember.Component.extend({
@observes("postStream.stream.[]")
_updateBar() {
- Ember.run.scheduleOnce("afterRender", this, this._updateProgressBar);
+ scheduleOnce("afterRender", this, this._updateProgressBar);
},
_topicScrolled(event) {
@@ -99,16 +102,11 @@ export default Ember.Component.extend({
const prevEvent = this.prevEvent;
if (prevEvent) {
- Ember.run.scheduleOnce(
- "afterRender",
- this,
- this._topicScrolled,
- prevEvent
- );
+ scheduleOnce("afterRender", this, this._topicScrolled, prevEvent);
} else {
- Ember.run.scheduleOnce("afterRender", this, this._updateProgressBar);
+ scheduleOnce("afterRender", this, this._updateProgressBar);
}
- Ember.run.scheduleOnce("afterRender", this, this._dock);
+ scheduleOnce("afterRender", this, this._dock);
},
willDestroyElement() {
diff --git a/app/assets/javascripts/discourse/components/topic-status.js.es6 b/app/assets/javascripts/discourse/components/topic-status.js.es6
index d063847e83..dc3e0d14f6 100644
--- a/app/assets/javascripts/discourse/components/topic-status.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-status.js.es6
@@ -1,10 +1,11 @@
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import { escapeExpression } from "discourse/lib/utilities";
import TopicStatusIcons from "discourse/helpers/topic-status-icons";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
classNames: ["topic-statuses"],
diff --git a/app/assets/javascripts/discourse/components/topic-timeline.js.es6 b/app/assets/javascripts/discourse/components/topic-timeline.js.es6
index 17709a5fc7..9aa6541065 100644
--- a/app/assets/javascripts/discourse/components/topic-timeline.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-timeline.js.es6
@@ -1,3 +1,4 @@
+import { next } from "@ember/runloop";
import MountWidget from "discourse/components/mount-widget";
import Docking from "discourse/mixins/docking";
import { observes } from "ember-addons/ember-computed-decorators";
@@ -58,7 +59,8 @@ export default MountWidget.extend(Docking, {
const mainOffset = $("#main").offset();
const offsetTop = mainOffset ? mainOffset.top : 0;
const topicTop = $(".container.posts").offset().top - offsetTop;
- const topicBottom = $("#topic-bottom").offset().top;
+ const topicBottom =
+ $("#topic-bottom").offset().top - $("#main-outlet").offset().top;
const timeline = this.element.querySelector(".timeline-container");
const timelineHeight = (timeline && timeline.offsetHeight) || 400;
const footerHeight = $(".timeline-footer-controls").outerHeight(true) || 0;
@@ -93,7 +95,7 @@ export default MountWidget.extend(Docking, {
this._super(...arguments);
if (this.fullscreen && !this.addShowClass) {
- Ember.run.next(() => {
+ next(() => {
this.set("addShowClass", true);
this.queueRerender();
});
diff --git a/app/assets/javascripts/discourse/components/topic-timer-info.js.es6 b/app/assets/javascripts/discourse/components/topic-timer-info.js.es6
index 288e61b3bb..bb26e0caba 100644
--- a/app/assets/javascripts/discourse/components/topic-timer-info.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-timer-info.js.es6
@@ -1,10 +1,13 @@
+import { cancel } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import Component from "@ember/component";
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import Category from "discourse/models/category";
import computed from "ember-addons/ember-computed-decorators";
import { REMINDER_TYPE } from "discourse/controllers/edit-topic-timer";
-export default Ember.Component.extend(
+export default Component.extend(
bufferedRender({
classNames: ["topic-status-info"],
_delayedRerender: null,
@@ -84,11 +87,7 @@ export default Ember.Component.extend(
// TODO Sam: concerned this can cause a heavy rerender loop
if (!Ember.testing) {
- this._delayedRerender = Ember.run.later(
- this,
- this.rerender,
- rerenderDelay
- );
+ this._delayedRerender = later(this, this.rerender, rerenderDelay);
}
}
},
@@ -109,7 +108,7 @@ export default Ember.Component.extend(
$(this.element).off("click.topic-timer-remove", this.removeTopicTimer);
if (this._delayedRerender) {
- Ember.run.cancel(this._delayedRerender);
+ cancel(this._delayedRerender);
}
},
diff --git a/app/assets/javascripts/discourse/components/topic-title.js.es6 b/app/assets/javascripts/discourse/components/topic-title.js.es6
index 17f99b48ee..7bbc478cb3 100644
--- a/app/assets/javascripts/discourse/components/topic-title.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-title.js.es6
@@ -1,5 +1,6 @@
+import Component from "@ember/component";
import KeyEnterEscape from "discourse/mixins/key-enter-escape";
-export default Ember.Component.extend(KeyEnterEscape, {
+export default Component.extend(KeyEnterEscape, {
elementId: "topic-title"
});
diff --git a/app/assets/javascripts/discourse/components/track-selected.js.es6 b/app/assets/javascripts/discourse/components/track-selected.js.es6
index bf720378b7..241cb64c7c 100644
--- a/app/assets/javascripts/discourse/components/track-selected.js.es6
+++ b/app/assets/javascripts/discourse/components/track-selected.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "span",
selectionChanged: function() {
const selected = this.selected;
diff --git a/app/assets/javascripts/discourse/components/user-badge.js.es6 b/app/assets/javascripts/discourse/components/user-badge.js.es6
index bca90d4435..85de291634 100644
--- a/app/assets/javascripts/discourse/components/user-badge.js.es6
+++ b/app/assets/javascripts/discourse/components/user-badge.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "span",
@computed("count")
diff --git a/app/assets/javascripts/discourse/components/user-card-contents.js.es6 b/app/assets/javascripts/discourse/components/user-card-contents.js.es6
index 981cbb125d..d7c6eac785 100644
--- a/app/assets/javascripts/discourse/components/user-card-contents.js.es6
+++ b/app/assets/javascripts/discourse/components/user-card-contents.js.es6
@@ -1,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import { alias, gte, and, gt, not, or } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import Component from "@ember/component";
import {
default as computed,
observes
@@ -9,214 +13,196 @@ import CanCheckEmails from "discourse/mixins/can-check-emails";
import CardContentsBase from "discourse/mixins/card-contents-base";
import CleansUp from "discourse/mixins/cleans-up";
import { prioritizeNameInUx } from "discourse/lib/settings";
+import { set } from "@ember/object";
-export default Ember.Component.extend(
- CardContentsBase,
- CanCheckEmails,
- CleansUp,
- {
- elementId: "user-card",
- triggeringLinkClass: "mention",
- classNameBindings: [
- "visible:show",
- "showBadges",
- "user.card_background::no-bg",
- "isFixed:fixed",
- "usernameClass"
- ],
- allowBackgrounds: setting("allow_profile_backgrounds"),
- showBadges: setting("enable_badges"),
+export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
+ elementId: "user-card",
+ triggeringLinkClass: "mention",
+ classNameBindings: [
+ "visible:show",
+ "showBadges",
+ "user.card_background::no-bg",
+ "isFixed:fixed",
+ "usernameClass"
+ ],
+ allowBackgrounds: setting("allow_profile_backgrounds"),
+ showBadges: setting("enable_badges"),
- postStream: Ember.computed.alias("topic.postStream"),
- enoughPostsForFiltering: Ember.computed.gte("topicPostCount", 2),
- showFilter: Ember.computed.and(
- "viewingTopic",
- "postStream.hasNoFilters",
- "enoughPostsForFiltering"
- ),
- showName: propertyNotEqual("user.name", "user.username"),
- hasUserFilters: Ember.computed.gt("postStream.userFilters.length", 0),
- showMoreBadges: Ember.computed.gt("moreBadgesCount", 0),
- showDelete: Ember.computed.and(
- "viewingAdmin",
- "showName",
- "user.canBeDeleted"
- ),
- linkWebsite: Ember.computed.not("user.isBasic"),
- hasLocationOrWebsite: Ember.computed.or(
- "user.location",
- "user.website_name"
- ),
- isSuspendedOrHasBio: Ember.computed.or(
- "user.suspend_reason",
- "user.bio_cooked"
- ),
- showCheckEmail: Ember.computed.and("user.staged", "canCheckEmails"),
+ postStream: alias("topic.postStream"),
+ enoughPostsForFiltering: gte("topicPostCount", 2),
+ showFilter: and(
+ "viewingTopic",
+ "postStream.hasNoFilters",
+ "enoughPostsForFiltering"
+ ),
+ showName: propertyNotEqual("user.name", "user.username"),
+ hasUserFilters: gt("postStream.userFilters.length", 0),
+ showMoreBadges: gt("moreBadgesCount", 0),
+ showDelete: and("viewingAdmin", "showName", "user.canBeDeleted"),
+ linkWebsite: not("user.isBasic"),
+ hasLocationOrWebsite: or("user.location", "user.website_name"),
+ isSuspendedOrHasBio: or("user.suspend_reason", "user.bio_cooked"),
+ showCheckEmail: and("user.staged", "canCheckEmails"),
- user: null,
+ user: null,
- // If inside a topic
- topicPostCount: null,
+ // If inside a topic
+ topicPostCount: null,
- @computed("user.staff")
- staff: isStaff => (isStaff ? "staff" : ""),
+ @computed("user.staff")
+ staff: isStaff => (isStaff ? "staff" : ""),
- @computed("user.trust_level")
- newUser: trustLevel => (trustLevel === 0 ? "new-user" : ""),
+ @computed("user.trust_level")
+ newUser: trustLevel => (trustLevel === 0 ? "new-user" : ""),
- @computed("user.name")
- nameFirst(name) {
- return prioritizeNameInUx(name, this.siteSettings);
- },
+ @computed("user.name")
+ nameFirst(name) {
+ return prioritizeNameInUx(name, this.siteSettings);
+ },
- @computed("username")
- usernameClass: username => (username ? `user-card-${username}` : ""),
+ @computed("username")
+ usernameClass: username => (username ? `user-card-${username}` : ""),
- @computed("username", "topicPostCount")
- togglePostsLabel(username, count) {
- return I18n.t("topic.filter_to", { username, count });
- },
+ @computed("username", "topicPostCount")
+ togglePostsLabel(username, count) {
+ return I18n.t("topic.filter_to", { username, count });
+ },
- @computed("user.user_fields.@each.value")
- publicUserFields() {
- const siteUserFields = this.site.get("user_fields");
- if (!Ember.isEmpty(siteUserFields)) {
- const userFields = this.get("user.user_fields");
- return siteUserFields
- .filterBy("show_on_user_card", true)
- .sortBy("position")
- .map(field => {
- Ember.set(field, "dasherized_name", field.get("name").dasherize());
- const value = userFields ? userFields[field.get("id")] : null;
- return Ember.isEmpty(value)
- ? null
- : Ember.Object.create({ value, field });
- })
- .compact();
- }
- },
-
- @computed("user.trust_level")
- removeNoFollow(trustLevel) {
- return trustLevel > 2 && !this.siteSettings.tl3_links_no_follow;
- },
-
- @computed("user.badge_count", "user.featured_user_badges.length")
- moreBadgesCount: (badgeCount, badgeLength) => badgeCount - badgeLength,
-
- @computed("user.time_read", "user.recent_time_read")
- showRecentTimeRead(timeRead, recentTimeRead) {
- return timeRead !== recentTimeRead && recentTimeRead !== 0;
- },
-
- @computed("user.recent_time_read")
- recentTimeRead(recentTimeReadSeconds) {
- return durationTiny(recentTimeReadSeconds);
- },
-
- @computed("showRecentTimeRead", "user.time_read", "recentTimeRead")
- timeReadTooltip(showRecent, timeRead, recentTimeRead) {
- if (showRecent) {
- return I18n.t("time_read_recently_tooltip", {
- time_read: durationTiny(timeRead),
- recent_time_read: recentTimeRead
- });
- } else {
- return I18n.t("time_read_tooltip", {
- time_read: durationTiny(timeRead)
- });
- }
- },
-
- @observes("user.card_background_upload_url")
- addBackground() {
- if (!this.allowBackgrounds) {
- return;
- }
-
- const thisElem = this.element;
- if (!thisElem) {
- return;
- }
-
- const url = this.get("user.card_background_upload_url");
- const bg = Ember.isEmpty(url)
- ? ""
- : `url(${Discourse.getURLWithCDN(url)})`;
- thisElem.style.backgroundImage = bg;
- },
-
- _showCallback(username, $target) {
- this._positionCard($target);
- this.setProperties({ visible: true, loading: true });
-
- const args = { stats: false };
- args.include_post_count_for = this.get("topic.id");
- User.findByUsername(username, args)
- .then(user => {
- if (user.topic_post_count) {
- this.set(
- "topicPostCount",
- user.topic_post_count[args.include_post_count_for]
- );
- }
- this.setProperties({ user });
+ @computed("user.user_fields.@each.value")
+ publicUserFields() {
+ const siteUserFields = this.site.get("user_fields");
+ if (!isEmpty(siteUserFields)) {
+ const userFields = this.get("user.user_fields");
+ return siteUserFields
+ .filterBy("show_on_user_card", true)
+ .sortBy("position")
+ .map(field => {
+ set(field, "dasherized_name", field.get("name").dasherize());
+ const value = userFields ? userFields[field.get("id")] : null;
+ return isEmpty(value) ? null : EmberObject.create({ value, field });
})
- .catch(() => this._close())
- .finally(() => this.set("loading", null));
- },
+ .compact();
+ }
+ },
- _close() {
- this._super(...arguments);
+ @computed("user.trust_level")
+ removeNoFollow(trustLevel) {
+ return trustLevel > 2 && !this.siteSettings.tl3_links_no_follow;
+ },
- this.setProperties({
- user: null,
- topicPostCount: null
+ @computed("user.badge_count", "user.featured_user_badges.length")
+ moreBadgesCount: (badgeCount, badgeLength) => badgeCount - badgeLength,
+
+ @computed("user.time_read", "user.recent_time_read")
+ showRecentTimeRead(timeRead, recentTimeRead) {
+ return timeRead !== recentTimeRead && recentTimeRead !== 0;
+ },
+
+ @computed("user.recent_time_read")
+ recentTimeRead(recentTimeReadSeconds) {
+ return durationTiny(recentTimeReadSeconds);
+ },
+
+ @computed("showRecentTimeRead", "user.time_read", "recentTimeRead")
+ timeReadTooltip(showRecent, timeRead, recentTimeRead) {
+ if (showRecent) {
+ return I18n.t("time_read_recently_tooltip", {
+ time_read: durationTiny(timeRead),
+ recent_time_read: recentTimeRead
});
- },
+ } else {
+ return I18n.t("time_read_tooltip", {
+ time_read: durationTiny(timeRead)
+ });
+ }
+ },
- cleanUp() {
+ @observes("user.card_background_upload_url")
+ addBackground() {
+ if (!this.allowBackgrounds) {
+ return;
+ }
+
+ const thisElem = this.element;
+ if (!thisElem) {
+ return;
+ }
+
+ const url = this.get("user.card_background_upload_url");
+ const bg = isEmpty(url) ? "" : `url(${Discourse.getURLWithCDN(url)})`;
+ thisElem.style.backgroundImage = bg;
+ },
+
+ _showCallback(username, $target) {
+ this._positionCard($target);
+ this.setProperties({ visible: true, loading: true });
+
+ const args = { stats: false };
+ args.include_post_count_for = this.get("topic.id");
+ User.findByUsername(username, args)
+ .then(user => {
+ if (user.topic_post_count) {
+ this.set(
+ "topicPostCount",
+ user.topic_post_count[args.include_post_count_for]
+ );
+ }
+ this.setProperties({ user });
+ })
+ .catch(() => this._close())
+ .finally(() => this.set("loading", null));
+ },
+
+ _close() {
+ this._super(...arguments);
+
+ this.setProperties({
+ user: null,
+ topicPostCount: null
+ });
+ },
+
+ cleanUp() {
+ this._close();
+ },
+
+ actions: {
+ close() {
this._close();
},
- actions: {
- close() {
- this._close();
- },
+ composePM(user, post) {
+ this._close();
- composePM(user, post) {
- this._close();
+ Ember.getOwner(this)
+ .lookup("router:main")
+ .send("composePrivateMessage", user, post);
+ },
- Ember.getOwner(this)
- .lookup("router:main")
- .send("composePrivateMessage", user, post);
- },
+ cancelFilter() {
+ const postStream = this.postStream;
+ postStream.cancelFilter();
+ postStream.refresh();
+ this._close();
+ },
- cancelFilter() {
- const postStream = this.postStream;
- postStream.cancelFilter();
- postStream.refresh();
- this._close();
- },
+ togglePosts() {
+ this.togglePosts(this.user);
+ this._close();
+ },
- togglePosts() {
- this.togglePosts(this.user);
- this._close();
- },
+ deleteUser() {
+ this.user.delete();
+ this._close();
+ },
- deleteUser() {
- this.user.delete();
- this._close();
- },
+ showUser(username) {
+ this.showUser(username);
+ this._close();
+ },
- showUser(username) {
- this.showUser(username);
- this._close();
- },
-
- checkEmail(user) {
- user.checkEmail();
- }
+ checkEmail(user) {
+ user.checkEmail();
}
}
-);
+});
diff --git a/app/assets/javascripts/discourse/components/user-field.js.es6 b/app/assets/javascripts/discourse/components/user-field.js.es6
index 1585e9a3a5..b54cbafd0a 100644
--- a/app/assets/javascripts/discourse/components/user-field.js.es6
+++ b/app/assets/javascripts/discourse/components/user-field.js.es6
@@ -1,12 +1,24 @@
+import Component from "@ember/component";
import { fmt } from "discourse/lib/computed";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
- classNameBindings: [":user-field", "field.field_type"],
+export default Component.extend({
+ classNameBindings: [":user-field", "field.field_type", "customFieldClass"],
layoutName: fmt("field.field_type", "components/user-fields/%@"),
@computed
noneLabel() {
return "user_fields.none";
+ },
+
+ @computed("field.name")
+ customFieldClass(fieldName) {
+ if (fieldName) {
+ fieldName = fieldName
+ .replace(/\s+/g, "-")
+ .replace(/[!\"#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, "")
+ .toLowerCase();
+ return fieldName && `user-field-${fieldName}`;
+ }
}
});
diff --git a/app/assets/javascripts/discourse/components/user-flag-percentage.js.es6 b/app/assets/javascripts/discourse/components/user-flag-percentage.js.es6
index 874f19c7bb..5c24fb70af 100644
--- a/app/assets/javascripts/discourse/components/user-flag-percentage.js.es6
+++ b/app/assets/javascripts/discourse/components/user-flag-percentage.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
@computed("percentage")
diff --git a/app/assets/javascripts/discourse/components/user-info.js.es6 b/app/assets/javascripts/discourse/components/user-info.js.es6
index 21a1347775..5873829a25 100644
--- a/app/assets/javascripts/discourse/components/user-info.js.es6
+++ b/app/assets/javascripts/discourse/components/user-info.js.es6
@@ -1,3 +1,5 @@
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
import { userPath } from "discourse/lib/url";
@@ -5,7 +7,7 @@ export function normalize(name) {
return name.replace(/[\-\_ \.]/g, "").toLowerCase();
}
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [":user-info", "size"],
attributeBindings: ["data-username"],
size: "small",
@@ -15,10 +17,10 @@ export default Ember.Component.extend({
return userPath(username);
},
- "data-username": Ember.computed.alias("user.username"),
+ "data-username": alias("user.username"),
// TODO: In later ember releases `hasBlock` works without this
- hasBlock: Ember.computed.alias("template"),
+ hasBlock: alias("template"),
@computed("user.name", "user.username")
name(name, username) {
diff --git a/app/assets/javascripts/discourse/components/user-link.js.es6 b/app/assets/javascripts/discourse/components/user-link.js.es6
index 7b86bed4fd..6ea395e5f0 100644
--- a/app/assets/javascripts/discourse/components/user-link.js.es6
+++ b/app/assets/javascripts/discourse/components/user-link.js.es6
@@ -1,6 +1,8 @@
-export default Ember.Component.extend({
+import { alias } from "@ember/object/computed";
+import Component from "@ember/component";
+export default Component.extend({
tagName: "a",
attributeBindings: ["href", "data-user-card"],
- href: Ember.computed.alias("user.path"),
- "data-user-card": Ember.computed.alias("user.username")
+ href: alias("user.path"),
+ "data-user-card": alias("user.username")
});
diff --git a/app/assets/javascripts/discourse/components/user-selector.js.es6 b/app/assets/javascripts/discourse/components/user-selector.js.es6
index 2cc95441ed..772777543c 100644
--- a/app/assets/javascripts/discourse/components/user-selector.js.es6
+++ b/app/assets/javascripts/discourse/components/user-selector.js.es6
@@ -1,3 +1,4 @@
+import { isEmpty } from "@ember/utils";
import { on, observes } from "ember-addons/ember-computed-decorators";
import TextField from "discourse/components/text-field";
import userSearch from "discourse/lib/user-search";
@@ -130,7 +131,7 @@ export default TextField.extend({
// THIS IS A HUGE HACK TO SUPPORT CLEARING THE INPUT
@observes("usernames")
_clearInput() {
- if (arguments.length > 1 && Ember.isEmpty(this.usernames)) {
+ if (arguments.length > 1 && isEmpty(this.usernames)) {
$(this.element)
.parent()
.find("a")
diff --git a/app/assets/javascripts/discourse/components/user-stat.js.es6 b/app/assets/javascripts/discourse/components/user-stat.js.es6
index 879198734c..1f3fe86644 100644
--- a/app/assets/javascripts/discourse/components/user-stat.js.es6
+++ b/app/assets/javascripts/discourse/components/user-stat.js.es6
@@ -1,6 +1,8 @@
-export default Ember.Component.extend({
+import { equal } from "@ember/object/computed";
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["user-stat"],
type: "number",
- isNumber: Ember.computed.equal("type", "number"),
- isDuration: Ember.computed.equal("type", "duration")
+ isNumber: equal("type", "number"),
+ isDuration: equal("type", "duration")
});
diff --git a/app/assets/javascripts/discourse/components/user-stream-item.js.es6 b/app/assets/javascripts/discourse/components/user-stream-item.js.es6
index 332e16520d..f0c5ca36e5 100644
--- a/app/assets/javascripts/discourse/components/user-stream-item.js.es6
+++ b/app/assets/javascripts/discourse/components/user-stream-item.js.es6
@@ -1,7 +1,8 @@
+import Component from "@ember/component";
import { propertyEqual } from "discourse/lib/computed";
import { actionDescription } from "discourse/widgets/post-small-action";
-export default Ember.Component.extend({
+export default Component.extend({
classNameBindings: [
":user-stream-item",
":item", // DEPRECATED: 'item' class
diff --git a/app/assets/javascripts/discourse/components/user-stream.js.es6 b/app/assets/javascripts/discourse/components/user-stream.js.es6
index 7054358457..79543dd394 100644
--- a/app/assets/javascripts/discourse/components/user-stream.js.es6
+++ b/app/assets/javascripts/discourse/components/user-stream.js.es6
@@ -1,3 +1,5 @@
+import { schedule } from "@ember/runloop";
+import Component from "@ember/component";
import LoadMore from "discourse/mixins/load-more";
import ClickTrack from "discourse/lib/click-track";
import Post from "discourse/models/post";
@@ -5,9 +7,10 @@ import DiscourseURL from "discourse/lib/url";
import Draft from "discourse/models/draft";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { getOwner } from "discourse-common/lib/get-owner";
+import { on } from "@ember/object/evented";
-export default Ember.Component.extend(LoadMore, {
- _initialize: function() {
+export default Component.extend(LoadMore, {
+ _initialize: on("init", function() {
const filter = this.get("stream.filter");
if (filter) {
this.set("classNames", [
@@ -15,17 +18,17 @@ export default Ember.Component.extend(LoadMore, {
"filter-" + filter.toString().replace(",", "-")
]);
}
- }.on("init"),
+ }),
loading: false,
eyelineSelector: ".user-stream .item",
classNames: ["user-stream"],
_scrollTopOnModelChange: function() {
- Ember.run.schedule("afterRender", () => $(document).scrollTop(0));
+ schedule("afterRender", () => $(document).scrollTop(0));
}.observes("stream.user.id"),
- _inserted: function() {
+ _inserted: on("didInsertElement", function() {
this.bindScrolling({ name: "user-stream-view" });
$(window).on("resize.discourse-on-scroll", () => this.scrolled());
@@ -38,17 +41,17 @@ export default Ember.Component.extend(LoadMore, {
$(this.element).on("click.discourse-redirect", ".excerpt a", function(e) {
return ClickTrack.trackClick(e);
});
- }.on("didInsertElement"),
+ }),
// This view is being removed. Shut down operations
- _destroyed: function() {
+ _destroyed: on("willDestroyElement", function() {
this.unbindScrolling("user-stream-view");
$(window).unbind("resize.discourse-on-scroll");
$(this.element).off("click.details-disabled", "details.disabled");
// Unbind link tracking
$(this.element).off("click.discourse-redirect", ".excerpt a");
- }.on("willDestroyElement"),
+ }),
actions: {
removeBookmark(userAction) {
diff --git a/app/assets/javascripts/discourse/components/user-summary-category-search.js.es6 b/app/assets/javascripts/discourse/components/user-summary-category-search.js.es6
index 86def06ee1..5206a83988 100644
--- a/app/assets/javascripts/discourse/components/user-summary-category-search.js.es6
+++ b/app/assets/javascripts/discourse/components/user-summary-category-search.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
@computed("user", "category")
diff --git a/app/assets/javascripts/discourse/components/user-summary-section.js.es6 b/app/assets/javascripts/discourse/components/user-summary-section.js.es6
index b5deb64dc4..d566ee18ab 100644
--- a/app/assets/javascripts/discourse/components/user-summary-section.js.es6
+++ b/app/assets/javascripts/discourse/components/user-summary-section.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
classNames: ["top-sub-section"]
});
diff --git a/app/assets/javascripts/discourse/components/user-summary-topic.js.es6 b/app/assets/javascripts/discourse/components/user-summary-topic.js.es6
index 145b770e51..790c675e49 100644
--- a/app/assets/javascripts/discourse/components/user-summary-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/user-summary-topic.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "li"
});
diff --git a/app/assets/javascripts/discourse/components/user-summary-topics-list.js.es6 b/app/assets/javascripts/discourse/components/user-summary-topics-list.js.es6
index 5035daa2a7..39970994da 100644
--- a/app/assets/javascripts/discourse/components/user-summary-topics-list.js.es6
+++ b/app/assets/javascripts/discourse/components/user-summary-topics-list.js.es6
@@ -1,9 +1,10 @@
+import Component from "@ember/component";
import computed from "ember-addons/ember-computed-decorators";
// should be kept in sync with 'UserSummary::MAX_SUMMARY_RESULTS'
const MAX_SUMMARY_RESULTS = 6;
-export default Ember.Component.extend({
+export default Component.extend({
tagName: "",
@computed("items.length")
diff --git a/app/assets/javascripts/discourse/components/user-summary-user.js.es6 b/app/assets/javascripts/discourse/components/user-summary-user.js.es6
index 145b770e51..790c675e49 100644
--- a/app/assets/javascripts/discourse/components/user-summary-user.js.es6
+++ b/app/assets/javascripts/discourse/components/user-summary-user.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Component.extend({
+import Component from "@ember/component";
+export default Component.extend({
tagName: "li"
});
diff --git a/app/assets/javascripts/discourse/components/watch-read.js.es6 b/app/assets/javascripts/discourse/components/watch-read.js.es6
index 68b1d1f480..16cc583f4f 100644
--- a/app/assets/javascripts/discourse/components/watch-read.js.es6
+++ b/app/assets/javascripts/discourse/components/watch-read.js.es6
@@ -1,6 +1,7 @@
+import Component from "@ember/component";
import isElementInViewport from "discourse/lib/is-element-in-viewport";
-export default Ember.Component.extend({
+export default Component.extend({
didInsertElement() {
this._super(...arguments);
const currentUser = this.currentUser;
diff --git a/app/assets/javascripts/discourse/controllers/about.js.es6 b/app/assets/javascripts/discourse/controllers/about.js.es6
index f17aac609b..85f26757ae 100644
--- a/app/assets/javascripts/discourse/controllers/about.js.es6
+++ b/app/assets/javascripts/discourse/controllers/about.js.es6
@@ -1,7 +1,9 @@
+import { gt } from "@ember/object/computed";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
- faqOverriden: Ember.computed.gt("siteSettings.faq_url.length", 0),
+export default Controller.extend({
+ faqOverriden: gt("siteSettings.faq_url.length", 0),
@computed
contactInfo() {
diff --git a/app/assets/javascripts/discourse/controllers/account-created-edit-email.js.es6 b/app/assets/javascripts/discourse/controllers/account-created-edit-email.js.es6
index b22fd6de9a..1002a90752 100644
--- a/app/assets/javascripts/discourse/controllers/account-created-edit-email.js.es6
+++ b/app/assets/javascripts/discourse/controllers/account-created-edit-email.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import { changeEmail } from "discourse/lib/user-activation";
import computed from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
accountCreated: null,
newEmail: null,
diff --git a/app/assets/javascripts/discourse/controllers/account-created-index.js.es6 b/app/assets/javascripts/discourse/controllers/account-created-index.js.es6
index ed822d3d3b..00d381a080 100644
--- a/app/assets/javascripts/discourse/controllers/account-created-index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/account-created-index.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import { resendActivationEmail } from "discourse/lib/user-activation";
-export default Ember.Controller.extend({
+export default Controller.extend({
actions: {
sendActivationEmail() {
resendActivationEmail(this.get("accountCreated.username")).then(() => {
diff --git a/app/assets/javascripts/discourse/controllers/activation-edit.js.es6 b/app/assets/javascripts/discourse/controllers/activation-edit.js.es6
index ebe73984d0..8fc90f6cf0 100644
--- a/app/assets/javascripts/discourse/controllers/activation-edit.js.es6
+++ b/app/assets/javascripts/discourse/controllers/activation-edit.js.es6
@@ -1,10 +1,12 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { extractError } from "discourse/lib/ajax-error";
import { changeEmail } from "discourse/lib/user-activation";
-export default Ember.Controller.extend(ModalFunctionality, {
- login: Ember.inject.controller(),
+export default Controller.extend(ModalFunctionality, {
+ login: inject(),
currentEmail: null,
newEmail: null,
diff --git a/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6 b/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6
index 13c3927d4a..83883ca5aa 100644
--- a/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6
+++ b/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6
@@ -1,8 +1,10 @@
+import { isEmpty } from "@ember/utils";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import computed from "ember-addons/ember-computed-decorators";
import { cookAsync } from "discourse/lib/text";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
post: null,
resolve: null,
reject: null,
@@ -12,7 +14,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
@computed("saving", "notice")
disabled(saving, notice) {
- return saving || Ember.isEmpty(notice);
+ return saving || isEmpty(notice);
},
onShow() {
diff --git a/app/assets/javascripts/discourse/controllers/application.js.es6 b/app/assets/javascripts/discourse/controllers/application.js.es6
index 7cd2898bf1..610e745e64 100644
--- a/app/assets/javascripts/discourse/controllers/application.js.es6
+++ b/app/assets/javascripts/discourse/controllers/application.js.es6
@@ -1,10 +1,12 @@
+import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { isAppWebview, isiOSPWA } from "discourse/lib/utilities";
-export default Ember.Controller.extend({
+export default Controller.extend({
showTop: true,
showFooter: false,
- router: Ember.inject.service(),
+ router: service(),
@computed
canSignUp() {
diff --git a/app/assets/javascripts/discourse/controllers/associate-account-confirm.js.es6 b/app/assets/javascripts/discourse/controllers/associate-account-confirm.js.es6
index e9685e0cf9..e138dc71db 100644
--- a/app/assets/javascripts/discourse/controllers/associate-account-confirm.js.es6
+++ b/app/assets/javascripts/discourse/controllers/associate-account-confirm.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
actions: {
finishConnect() {
ajax({
diff --git a/app/assets/javascripts/discourse/controllers/auth-token.js.es6 b/app/assets/javascripts/discourse/controllers/auth-token.js.es6
index 1d933fb191..a24f6a53b1 100644
--- a/app/assets/javascripts/discourse/controllers/auth-token.js.es6
+++ b/app/assets/javascripts/discourse/controllers/auth-token.js.es6
@@ -1,8 +1,10 @@
+import { next } from "@ember/runloop";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
import { userPath } from "discourse/lib/url";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
expanded: false,
onShow() {
@@ -23,7 +25,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
highlightSecure() {
this.send("closeModal");
- Ember.run.next(() => {
+ next(() => {
const $prefPasswordDiv = $(".pref-password");
$prefPasswordDiv.addClass("highlighted");
diff --git a/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6
index 624eb3ab22..1a23033580 100644
--- a/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6
+++ b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6
@@ -1,10 +1,11 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
import { allowsImages } from "discourse/lib/utilities";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
@computed(
"selected",
"user.system_avatar_upload_id",
diff --git a/app/assets/javascripts/discourse/controllers/badges/index.js.es6 b/app/assets/javascripts/discourse/controllers/badges/index.js.es6
index eb36dbe521..c1c4d8db27 100644
--- a/app/assets/javascripts/discourse/controllers/badges/index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/badges/index.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
@computed("model")
badgeGroups(model) {
var sorted = _.sortBy(model, function(badge) {
diff --git a/app/assets/javascripts/discourse/controllers/badges/show.js.es6 b/app/assets/javascripts/discourse/controllers/badges/show.js.es6
index d3411ae6d3..d1093c13bc 100644
--- a/app/assets/javascripts/discourse/controllers/badges/show.js.es6
+++ b/app/assets/javascripts/discourse/controllers/badges/show.js.es6
@@ -1,15 +1,18 @@
+import { inject } from "@ember/controller";
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
+import Badge from "discourse/models/badge";
import UserBadge from "discourse/models/user-badge";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-import BadgeSelectController from "discourse/mixins/badge-select-controller";
-export default Ember.Controller.extend(BadgeSelectController, {
+export default Controller.extend({
queryParams: ["username"],
noMoreBadges: false,
userBadges: null,
- application: Ember.inject.controller(),
+ application: inject(),
hiddenSetTitle: true,
@computed("userBadgesAll")
@@ -17,6 +20,16 @@ export default Ember.Controller.extend(BadgeSelectController, {
return userBadgesAll.filterBy("badge.allow_title", true);
},
+ @computed("filteredList")
+ selectableUserBadges(filteredList) {
+ return [
+ EmberObject.create({
+ badge: Badge.create({ name: I18n.t("badges.none") })
+ }),
+ ...filteredList.uniqBy("badge.name")
+ ];
+ },
+
@computed("username")
user(username) {
if (username) {
diff --git a/app/assets/javascripts/discourse/controllers/basic-modal-body.js.es6 b/app/assets/javascripts/discourse/controllers/basic-modal-body.js.es6
index 1ee99a7549..03d95d5cb2 100644
--- a/app/assets/javascripts/discourse/controllers/basic-modal-body.js.es6
+++ b/app/assets/javascripts/discourse/controllers/basic-modal-body.js.es6
@@ -1,5 +1,6 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
modal: null
});
diff --git a/app/assets/javascripts/discourse/controllers/bulk-notification-level.js.es6 b/app/assets/javascripts/discourse/controllers/bulk-notification-level.js.es6
index f34195bf8a..0d8ac58ca2 100644
--- a/app/assets/javascripts/discourse/controllers/bulk-notification-level.js.es6
+++ b/app/assets/javascripts/discourse/controllers/bulk-notification-level.js.es6
@@ -1,9 +1,12 @@
+import { empty } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { topicLevels } from "discourse/lib/notification-levels";
// Support for changing the notification level of various topics
-export default Ember.Controller.extend({
- topicBulkActions: Ember.inject.controller(),
+export default Controller.extend({
+ topicBulkActions: inject(),
notificationLevelId: null,
@computed
@@ -17,7 +20,7 @@ export default Ember.Controller.extend({
});
},
- disabled: Ember.computed.empty("notificationLevelId"),
+ disabled: empty("notificationLevelId"),
actions: {
changeNotificationLevel() {
diff --git a/app/assets/javascripts/discourse/controllers/change-owner.js.es6 b/app/assets/javascripts/discourse/controllers/change-owner.js.es6
index 0738db8740..10ed05c04f 100644
--- a/app/assets/javascripts/discourse/controllers/change-owner.js.es6
+++ b/app/assets/javascripts/discourse/controllers/change-owner.js.es6
@@ -1,28 +1,24 @@
+import { isEmpty } from "@ember/utils";
+import { alias } from "@ember/object/computed";
+import { next } from "@ember/runloop";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import DiscourseURL from "discourse/lib/url";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(ModalFunctionality, {
- topicController: Ember.inject.controller("topic"),
+export default Controller.extend(ModalFunctionality, {
+ topicController: inject("topic"),
saving: false,
new_user: null,
- selectedPostsCount: Ember.computed.alias(
- "topicController.selectedPostsCount"
- ),
- selectedPostsUsername: Ember.computed.alias(
- "topicController.selectedPostsUsername"
- ),
+ selectedPostsCount: alias("topicController.selectedPostsCount"),
+ selectedPostsUsername: alias("topicController.selectedPostsUsername"),
@computed("saving", "new_user")
buttonDisabled(saving, newUser) {
- return saving || Ember.isEmpty(newUser);
- },
-
- @computed("saving")
- buttonTitle(saving) {
- return saving ? I18n.t("saving") : I18n.t("topic.change_owner.action");
+ return saving || isEmpty(newUser);
},
onShow() {
@@ -51,7 +47,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
if (this.get("topicController.multiSelect")) {
this.topicController.send("toggleMultiSelect");
}
- Ember.run.next(() =>
+ next(() =>
DiscourseURL.routeTo(this.get("topicController.model.url"))
);
},
diff --git a/app/assets/javascripts/discourse/controllers/change-timestamp.js.es6 b/app/assets/javascripts/discourse/controllers/change-timestamp.js.es6
index 6d64eb32e8..9a29c747d7 100644
--- a/app/assets/javascripts/discourse/controllers/change-timestamp.js.es6
+++ b/app/assets/javascripts/discourse/controllers/change-timestamp.js.es6
@@ -1,11 +1,15 @@
+import { isEmpty } from "@ember/utils";
+import { next } from "@ember/runloop";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import computed from "ember-addons/ember-computed-decorators";
import DiscourseURL from "discourse/lib/url";
import Topic from "discourse/models/topic";
// Modal related to changing the timestamp of posts
-export default Ember.Controller.extend(ModalFunctionality, {
- topicController: Ember.inject.controller("topic"),
+export default Controller.extend(ModalFunctionality, {
+ topicController: inject("topic"),
saving: false,
date: "",
time: "",
@@ -28,7 +32,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
@computed("saving", "date", "validTimestamp")
buttonDisabled(saving, date, validTimestamp) {
if (saving || validTimestamp) return true;
- return Ember.isEmpty(date);
+ return isEmpty(date);
},
onShow() {
@@ -45,7 +49,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
.then(() => {
this.send("closeModal");
this.setProperties({ date: "", time: "", saving: false });
- Ember.run.next(() => DiscourseURL.routeTo(topic.url));
+ next(() => DiscourseURL.routeTo(topic.url));
})
.catch(() =>
this.flash(I18n.t("topic.change_timestamp.error"), "alert-error")
diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6
index b96051e906..df26812280 100644
--- a/app/assets/javascripts/discourse/controllers/composer.js.es6
+++ b/app/assets/javascripts/discourse/controllers/composer.js.es6
@@ -1,3 +1,9 @@
+import { isEmpty } from "@ember/utils";
+import { and, or, alias, reads } from "@ember/object/computed";
+import { debounce } from "@ember/runloop";
+import { inject as service } from "@ember/service";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import DiscourseURL from "discourse/lib/url";
import Quote from "discourse/lib/quote";
import Draft from "discourse/models/draft";
@@ -18,6 +24,7 @@ import {
import { emojiUnescape } from "discourse/lib/text";
import { shortDate } from "discourse/lib/formatter";
import { SAVE_LABELS, SAVE_ICONS } from "discourse/models/composer";
+import { Promise } from "rsvp";
function loadDraft(store, opts) {
opts = opts || {};
@@ -39,26 +46,21 @@ function loadDraft(store, opts) {
((draft.title && draft.title !== "") || (draft.reply && draft.reply !== ""))
) {
const composer = store.createRecord("composer");
+ const serializedFields = Composer.serializedFieldsForDraft();
- composer.open({
+ let attrs = {
draftKey,
draftSequence,
- action: draft.action,
- title: draft.title,
- categoryId: draft.categoryId || opts.categoryId,
- postId: draft.postId,
- archetypeId: draft.archetypeId,
- reply: draft.reply,
- metaData: draft.metaData,
- usernames: draft.usernames,
draft: true,
- composerState: Composer.DRAFT,
- composerTime: draft.composerTime,
- typingTime: draft.typingTime,
- whisper: draft.whisper,
- tags: draft.tags,
- noBump: draft.noBump
+ composerState: Composer.DRAFT
+ };
+
+ serializedFields.forEach(f => {
+ attrs[f] = draft[f] || opts[f];
});
+
+ composer.open(attrs);
+
return composer;
}
}
@@ -79,18 +81,10 @@ export function addPopupMenuOptionsCallback(callback) {
_popupMenuOptionsCallbacks.push(callback);
}
-export default Ember.Controller.extend({
- topicController: Ember.inject.controller("topic"),
- router: Ember.inject.service(),
+export default Controller.extend({
+ topicController: inject("topic"),
+ router: service(),
- replyAsNewTopicDraft: Ember.computed.equal(
- "model.draftKey",
- Composer.REPLY_AS_NEW_TOPIC_KEY
- ),
- replyAsNewPrivateMessageDraft: Ember.computed.equal(
- "model.draftKey",
- Composer.REPLY_AS_NEW_PRIVATE_MESSAGE_KEY
- ),
checkedMessages: false,
messageCount: null,
showEditReason: false,
@@ -103,9 +97,9 @@ export default Ember.Controller.extend({
topic: null,
linkLookup: null,
showPreview: true,
- forcePreview: Ember.computed.and("site.mobileView", "showPreview"),
- whisperOrUnlistTopic: Ember.computed.or("isWhispering", "model.unlistTopic"),
- categories: Ember.computed.alias("site.categoriesList"),
+ forcePreview: and("site.mobileView", "showPreview"),
+ whisperOrUnlistTopic: or("isWhispering", "model.unlistTopic"),
+ categories: alias("site.categoriesList"),
@on("init")
_setupPreview() {
@@ -187,7 +181,7 @@ export default Ember.Controller.extend({
}
}),
- topicModel: Ember.computed.alias("topicController.model"),
+ topicModel: alias("topicController.model"),
@computed("model.canEditTitle", "model.creatingPrivateMessage")
canEditTags(canEditTitle, creatingPrivateMessage) {
@@ -199,9 +193,19 @@ export default Ember.Controller.extend({
);
},
- isStaffUser: Ember.computed.reads("currentUser.staff"),
+ @computed("model.editingPost", "model.topic.details.can_edit")
+ disableCategoryChooser(editingPost, canEditTopic) {
+ return editingPost && !canEditTopic;
+ },
- canUnlistTopic: Ember.computed.and("model.creatingTopic", "isStaffUser"),
+ @computed("model.editingPost", "model.topic.canEditTags")
+ disableTagsChooser(editingPost, canEditTags) {
+ return editingPost && !canEditTags;
+ },
+
+ isStaffUser: reads("currentUser.staff"),
+
+ canUnlistTopic: and("model.creatingTopic", "isStaffUser"),
@computed("canWhisper", "replyingToWhisper")
showWhisperToggle(canWhisper, replyingToWhisper) {
@@ -215,7 +219,7 @@ export default Ember.Controller.extend({
);
},
- isWhispering: Ember.computed.or("replyingToWhisper", "model.whisper"),
+ isWhispering: or("replyingToWhisper", "model.whisper"),
@computed("model.action", "isWhispering")
saveIcon(action, isWhispering) {
@@ -300,7 +304,7 @@ export default Ember.Controller.extend({
// We need exactly one user to issue a warning
if (
- Ember.isEmpty(usernames) ||
+ isEmpty(usernames) ||
usernames.split(",").length !== 1 ||
hasTargetGroups
) {
@@ -439,8 +443,8 @@ export default Ember.Controller.extend({
this.closeAutocomplete();
if (
- Ember.isEmpty(this.get("model.reply")) &&
- Ember.isEmpty(this.get("model.title"))
+ isEmpty(this.get("model.reply")) &&
+ isEmpty(this.get("model.title"))
) {
this.close();
} else {
@@ -589,7 +593,7 @@ export default Ember.Controller.extend({
}
},
- disableSubmit: Ember.computed.or("model.loading", "isUploading"),
+ disableSubmit: or("model.loading", "isUploading"),
save(force) {
if (this.disableSubmit) return;
@@ -682,20 +686,13 @@ export default Ember.Controller.extend({
}
}
- this.destroyDraft();
- this.close();
- this.appEvents.trigger("post-stream:refresh");
- return result;
+ return this.destroyDraft().then(() => {
+ this.close();
+ this.appEvents.trigger("post-stream:refresh");
+ return result;
+ });
}
- // If user "created a new topic/post" or "replied as a new topic" successfully, remove the draft.
- if (
- result.responseJson.action === "create_post" ||
- this.replyAsNewTopicDraft ||
- this.replyAsNewPrivateMessageDraft
- ) {
- this.destroyDraft();
- }
if (this.get("model.editingPost")) {
this.appEvents.trigger("post-stream:refresh", {
id: parseInt(result.responseJson.id)
@@ -726,7 +723,9 @@ export default Ember.Controller.extend({
})
.catch(error => {
composer.set("disableDrafts", false);
- this.appEvents.one("composer:will-open", () => bootbox.alert(error));
+ if (error) {
+ this.appEvents.one("composer:will-open", () => bootbox.alert(error));
+ }
});
if (
@@ -747,21 +746,21 @@ export default Ember.Controller.extend({
// Notify the composer messages controller that a reply has been typed. Some
// messages only appear after typing.
checkReplyLength() {
- if (!Ember.isEmpty("model.reply")) {
+ if (!isEmpty("model.reply")) {
this.appEvents.trigger("composer:typed-reply");
}
},
/**
- Open the composer view
+ Open the composer view
- @method open
- @param {Object} opts Options for creating a post
- @param {String} opts.action The action we're performing: edit, reply or createTopic
- @param {Discourse.Post} [opts.post] The post we're replying to
- @param {Discourse.Topic} [opts.topic] The topic we're replying to
- @param {String} [opts.quote] If we're opening a reply from a quote, the quote we're making
- **/
+ @method open
+ @param {Object} opts Options for creating a post
+ @param {String} opts.action The action we're performing: edit, reply or createTopic
+ @param {Discourse.Post} [opts.post] The post we're replying to
+ @param {Discourse.Topic} [opts.topic] The topic we're replying to
+ @param {String} [opts.quote] If we're opening a reply from a quote, the quote we're making
+ **/
open(opts) {
opts = opts || {};
@@ -786,11 +785,7 @@ export default Ember.Controller.extend({
});
// Scope the categories drop down to the category we opened the composer with.
- if (
- opts.categoryId &&
- opts.draftKey !== "reply_as_new_topic" &&
- !opts.disableScopedCategory
- ) {
+ if (opts.categoryId && !opts.disableScopedCategory) {
const category = this.site.categories.findBy("id", opts.categoryId);
if (category) {
this.set("scopedCategoryId", opts.categoryId);
@@ -807,7 +802,7 @@ export default Ember.Controller.extend({
composerModel = null;
}
- return new Ember.RSVP.Promise((resolve, reject) => {
+ return new Promise((resolve, reject) => {
if (composerModel && composerModel.replyDirty) {
// If we're already open, we don't have to do anything
if (
@@ -850,7 +845,6 @@ export default Ember.Controller.extend({
data.draft = undefined;
return data;
}
-
return this.confirmDraftAbandon(data);
})
.then(data => {
@@ -865,7 +859,9 @@ export default Ember.Controller.extend({
// otherwise, do the draft check async
else if (!opts.draft && !opts.skipDraftCheck) {
Draft.get(opts.draftKey)
- .then(data => this.confirmDraftAbandon(data))
+ .then(data => {
+ return this.confirmDraftAbandon(data);
+ })
.then(data => {
if (data.draft) {
opts.draft = data.draft;
@@ -946,9 +942,11 @@ export default Ember.Controller.extend({
this.send("clearTopicDraft");
}
- Draft.clear(key, this.get("model.draftSequence")).then(() =>
+ return Draft.clear(key, this.get("model.draftSequence")).then(() =>
this.appEvents.trigger("draft:destroyed", key)
);
+ } else {
+ return Promise.resolve();
}
},
@@ -965,7 +963,7 @@ export default Ember.Controller.extend({
}
if (_checkDraftPopup) {
- return new Ember.RSVP.Promise(resolve => {
+ return new Promise(resolve => {
bootbox.dialog(I18n.t("drafts.abandon.confirm"), [
{
label: I18n.t("drafts.abandon.no_value"),
@@ -988,13 +986,16 @@ export default Ember.Controller.extend({
},
cancelComposer(differentDraft = false) {
- return new Ember.RSVP.Promise(resolve => {
+ const keyPrefix =
+ this.model.action === "edit" ? "post.abandon_edit" : "post.abandon";
+
+ return new Promise(resolve => {
if (this.get("model.hasMetaData") || this.get("model.replyDirty")) {
- bootbox.dialog(I18n.t("post.abandon.confirm"), [
+ bootbox.dialog(I18n.t(keyPrefix + ".confirm"), [
{
label: differentDraft
- ? I18n.t("post.abandon.no_save_draft")
- : I18n.t("post.abandon.no_value"),
+ ? I18n.t(keyPrefix + ".no_save_draft")
+ : I18n.t(keyPrefix + ".no_value"),
callback: () => {
// cancel composer without destroying draft on new draft context
if (differentDraft) {
@@ -1005,24 +1006,26 @@ export default Ember.Controller.extend({
}
},
{
- label: I18n.t("post.abandon.yes_value"),
+ label: I18n.t(keyPrefix + ".yes_value"),
class: "btn-danger",
callback: result => {
if (result) {
- this.destroyDraft();
- this.model.clearState();
- this.close();
- resolve();
+ this.destroyDraft().then(() => {
+ this.model.clearState();
+ this.close();
+ resolve();
+ });
}
}
}
]);
} else {
// it is possible there is some sort of crazy draft with no body ... just give up on it
- this.destroyDraft();
- this.model.clearState();
- this.close();
- resolve();
+ this.destroyDraft().then(() => {
+ this.model.clearState();
+ this.close();
+ resolve();
+ });
}
});
},
@@ -1047,7 +1050,7 @@ export default Ember.Controller.extend({
@observes("model.reply", "model.title")
_shouldSaveDraft() {
- Ember.run.debounce(this, this._saveDraft, 2000);
+ debounce(this, this._saveDraft, 2000);
},
@computed("model.categoryId", "lastValidatedAt")
diff --git a/app/assets/javascripts/discourse/controllers/convert-to-public-topic.js.es6 b/app/assets/javascripts/discourse/controllers/convert-to-public-topic.js.es6
index 58ccfbcf88..2c08ff7884 100644
--- a/app/assets/javascripts/discourse/controllers/convert-to-public-topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/convert-to-public-topic.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
publicCategoryId: null,
saving: true,
diff --git a/app/assets/javascripts/discourse/controllers/create-account.js.es6 b/app/assets/javascripts/discourse/controllers/create-account.js.es6
index 1c8ecb254a..beb87d2d3a 100644
--- a/app/assets/javascripts/discourse/controllers/create-account.js.es6
+++ b/app/assets/javascripts/discourse/controllers/create-account.js.es6
@@ -1,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import { notEmpty, or, not } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { setting } from "discourse/lib/computed";
@@ -14,27 +18,27 @@ import UserFieldsValidation from "discourse/mixins/user-fields-validation";
import { userPath } from "discourse/lib/url";
import { findAll } from "discourse/models/login-method";
-export default Ember.Controller.extend(
+export default Controller.extend(
ModalFunctionality,
PasswordValidation,
UsernameValidation,
NameValidation,
UserFieldsValidation,
{
- login: Ember.inject.controller(),
+ login: inject(),
complete: false,
- accountPasswordConfirm: 0,
accountChallenge: 0,
+ accountHoneypot: 0,
formSubmitted: false,
rejectedEmails: Ember.A([]),
prefilledUsername: null,
userFields: null,
isDeveloper: false,
- hasAuthOptions: Ember.computed.notEmpty("authOptions"),
+ hasAuthOptions: notEmpty("authOptions"),
canCreateLocal: setting("enable_local_logins"),
- showCreateForm: Ember.computed.or("hasAuthOptions", "canCreateLocal"),
+ showCreateForm: or("hasAuthOptions", "canCreateLocal"),
resetForm() {
// We wrap the fields in a structure so we can assign a value
@@ -76,7 +80,7 @@ export default Ember.Controller.extend(
return false;
},
- usernameRequired: Ember.computed.not("authOptions.omit_username"),
+ usernameRequired: not("authOptions.omit_username"),
@computed
fullnameRequired() {
@@ -88,7 +92,7 @@ export default Ember.Controller.extend(
@computed("authOptions.auth_provider")
passwordRequired(authProvider) {
- return Ember.isEmpty(authProvider);
+ return isEmpty(authProvider);
},
@computed
@@ -105,7 +109,7 @@ export default Ember.Controller.extend(
@computed("accountEmail", "rejectedEmails.[]")
emailValidation(email, rejectedEmails) {
// If blank, fail without a reason
- if (Ember.isEmpty(email)) {
+ if (isEmpty(email)) {
return InputValidation.create({
failed: true
});
@@ -173,7 +177,7 @@ export default Ember.Controller.extend(
}
if (
this.get("emailValidation.ok") &&
- (Ember.isEmpty(this.accountUsername) || this.get("authOptions.email"))
+ (isEmpty(this.accountUsername) || this.get("authOptions.email"))
) {
// If email is valid and username has not been entered yet,
// or email and username were filled automatically by 3rd parth auth,
@@ -191,8 +195,16 @@ export default Ember.Controller.extend(
@on("init")
fetchConfirmationValue() {
return ajax(userPath("hp.json")).then(json => {
+ this._challengeDate = new Date();
+ // remove 30 seconds for jitter, make sure this works for at least
+ // 30 seconds so we don't have hard loops
+ this._challengeExpiry = parseInt(json.expires_in, 10) - 30;
+ if (this._challengeExpiry < 30) {
+ this._challengeExpiry = 30;
+ }
+
this.setProperties({
- accountPasswordConfirm: json.value,
+ accountHoneypot: json.value,
accountChallenge: json.challenge
.split("")
.reverse()
@@ -201,85 +213,100 @@ export default Ember.Controller.extend(
});
},
+ performAccountCreation() {
+ const attrs = this.getProperties(
+ "accountName",
+ "accountEmail",
+ "accountPassword",
+ "accountUsername",
+ "accountChallenge"
+ );
+
+ attrs["accountPasswordConfirm"] = this.accountHoneypot;
+
+ const userFields = this.userFields;
+ const destinationUrl = this.get("authOptions.destination_url");
+
+ if (!isEmpty(destinationUrl)) {
+ $.cookie("destination_url", destinationUrl, { path: "/" });
+ }
+
+ // Add the userfields to the data
+ if (!isEmpty(userFields)) {
+ attrs.userFields = {};
+ userFields.forEach(
+ f => (attrs.userFields[f.get("field.id")] = f.get("value"))
+ );
+ }
+
+ this.set("formSubmitted", true);
+ return Discourse.User.createAccount(attrs).then(
+ result => {
+ this.set("isDeveloper", false);
+ if (result.success) {
+ // invalidate honeypot
+ this._challengeExpiry = 1;
+
+ // Trigger the browser's password manager using the hidden static login form:
+ const $hidden_login_form = $("#hidden-login-form");
+ $hidden_login_form
+ .find("input[name=username]")
+ .val(attrs.accountUsername);
+ $hidden_login_form
+ .find("input[name=password]")
+ .val(attrs.accountPassword);
+ $hidden_login_form
+ .find("input[name=redirect]")
+ .val(userPath("account-created"));
+ $hidden_login_form.submit();
+ } else {
+ this.flash(
+ result.message || I18n.t("create_account.failed"),
+ "error"
+ );
+ if (result.is_developer) {
+ this.set("isDeveloper", true);
+ }
+ if (
+ result.errors &&
+ result.errors.email &&
+ result.errors.email.length > 0 &&
+ result.values
+ ) {
+ this.rejectedEmails.pushObject(result.values.email);
+ }
+ if (
+ result.errors &&
+ result.errors.password &&
+ result.errors.password.length > 0
+ ) {
+ this.rejectedPasswords.pushObject(attrs.accountPassword);
+ }
+ this.set("formSubmitted", false);
+ $.removeCookie("destination_url");
+ }
+ },
+ () => {
+ this.set("formSubmitted", false);
+ $.removeCookie("destination_url");
+ return this.flash(I18n.t("create_account.failed"), "error");
+ }
+ );
+ },
+
actions: {
externalLogin(provider) {
this.login.send("externalLogin", provider);
},
createAccount() {
- const attrs = this.getProperties(
- "accountName",
- "accountEmail",
- "accountPassword",
- "accountUsername",
- "accountPasswordConfirm",
- "accountChallenge"
- );
- const userFields = this.userFields;
- const destinationUrl = this.get("authOptions.destination_url");
-
- if (!Ember.isEmpty(destinationUrl)) {
- $.cookie("destination_url", destinationUrl, { path: "/" });
- }
-
- // Add the userfields to the data
- if (!Ember.isEmpty(userFields)) {
- attrs.userFields = {};
- userFields.forEach(
- f => (attrs.userFields[f.get("field.id")] = f.get("value"))
+ if (new Date() - this._challengeDate > 1000 * this._challengeExpiry) {
+ this.fetchConfirmationValue().then(() =>
+ this.performAccountCreation()
);
+ } else {
+ this.performAccountCreation();
}
-
- this.set("formSubmitted", true);
- return Discourse.User.createAccount(attrs).then(
- result => {
- this.set("isDeveloper", false);
- if (result.success) {
- // Trigger the browser's password manager using the hidden static login form:
- const $hidden_login_form = $("#hidden-login-form");
- $hidden_login_form
- .find("input[name=username]")
- .val(attrs.accountUsername);
- $hidden_login_form
- .find("input[name=password]")
- .val(attrs.accountPassword);
- $hidden_login_form
- .find("input[name=redirect]")
- .val(userPath("account-created"));
- $hidden_login_form.submit();
- } else {
- this.flash(
- result.message || I18n.t("create_account.failed"),
- "error"
- );
- if (result.is_developer) {
- this.set("isDeveloper", true);
- }
- if (
- result.errors &&
- result.errors.email &&
- result.errors.email.length > 0 &&
- result.values
- ) {
- this.rejectedEmails.pushObject(result.values.email);
- }
- if (
- result.errors &&
- result.errors.password &&
- result.errors.password.length > 0
- ) {
- this.rejectedPasswords.pushObject(attrs.accountPassword);
- }
- this.set("formSubmitted", false);
- $.removeCookie("destination_url");
- }
- },
- () => {
- this.set("formSubmitted", false);
- $.removeCookie("destination_url");
- return this.flash(I18n.t("create_account.failed"), "error");
- }
- );
}
}
}
diff --git a/app/assets/javascripts/discourse/controllers/discovery-sortable.js.es6 b/app/assets/javascripts/discourse/controllers/discovery-sortable.js.es6
index 4ce4284c55..d286a37dab 100644
--- a/app/assets/javascripts/discourse/controllers/discovery-sortable.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery-sortable.js.es6
@@ -1,3 +1,6 @@
+import { alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import DiscourseNavigation from "discourse/components/d-navigation";
// Just add query params here to have them automatically passed to topic list filters.
@@ -16,23 +19,23 @@ export const queryParams = {
// Basic controller options
const controllerOpts = {
- discoveryTopics: Ember.inject.controller("discovery/topics"),
+ discoveryTopics: inject("discovery/topics"),
queryParams: Object.keys(queryParams)
};
// Aliases for the values
controllerOpts.queryParams.forEach(
- p => (controllerOpts[p] = Ember.computed.alias(`discoveryTopics.${p}`))
+ p => (controllerOpts[p] = alias(`discoveryTopics.${p}`))
);
-const Controller = Ember.Controller.extend(controllerOpts);
+const SortableController = Controller.extend(controllerOpts);
export const addDiscoveryQueryParam = function(p, opts) {
queryParams[p] = opts;
const cOpts = {};
- cOpts[p] = Ember.computed.alias(`discoveryTopics.${p}`);
+ cOpts[p] = alias(`discoveryTopics.${p}`);
cOpts["queryParams"] = Object.keys(queryParams);
- Controller.reopen(cOpts);
+ SortableController.reopen(cOpts);
if (opts && opts.persisted) {
DiscourseNavigation.reopen({
@@ -41,4 +44,4 @@ export const addDiscoveryQueryParam = function(p, opts) {
}
};
-export default Controller;
+export default SortableController;
diff --git a/app/assets/javascripts/discourse/controllers/discovery.js.es6 b/app/assets/javascripts/discourse/controllers/discovery.js.es6
index 858058e4b0..6345bb8aa2 100644
--- a/app/assets/javascripts/discourse/controllers/discovery.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery.js.es6
@@ -1,16 +1,19 @@
+import { alias, not } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import DiscourseURL from "discourse/lib/url";
-export default Ember.Controller.extend({
- discoveryTopics: Ember.inject.controller("discovery/topics"),
- navigationCategory: Ember.inject.controller("navigation/category"),
- application: Ember.inject.controller(),
+export default Controller.extend({
+ discoveryTopics: inject("discovery/topics"),
+ navigationCategory: inject("navigation/category"),
+ application: inject(),
loading: false,
- category: Ember.computed.alias("navigationCategory.category"),
- noSubcategories: Ember.computed.alias("navigationCategory.noSubcategories"),
+ category: alias("navigationCategory.category"),
+ noSubcategories: alias("navigationCategory.noSubcategories"),
- loadedAllItems: Ember.computed.not("discoveryTopics.model.canLoadMore"),
+ loadedAllItems: not("discoveryTopics.model.canLoadMore"),
_showFooter: function() {
this.set("application.showFooter", this.loadedAllItems);
diff --git a/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6 b/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6
index 2d8cc9f9ed..81542214ef 100644
--- a/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery/categories.js.es6
@@ -1,5 +1,8 @@
+import { reads } from "@ember/object/computed";
+import { inject } from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import DiscoveryController from "discourse/controllers/discovery";
+import { dasherize } from "@ember/string";
const subcategoryStyleComponentNames = {
rows: "categories_only",
@@ -9,12 +12,12 @@ const subcategoryStyleComponentNames = {
};
export default DiscoveryController.extend({
- discovery: Ember.inject.controller(),
+ discovery: inject(),
// this makes sure the composer isn't scoping to a specific category
category: null,
- canEdit: Ember.computed.reads("currentUser.staff"),
+ canEdit: reads("currentUser.staff"),
@computed("model.categories.[].featuredTopics.length")
latestTopicOnly() {
@@ -42,7 +45,7 @@ export default DiscoveryController.extend({
parentCategory && style === "categories_and_latest_topics"
? "categories_only"
: style;
- return Ember.String.dasherize(componentName);
+ return dasherize(componentName);
},
actions: {
refresh() {
diff --git a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6 b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
index c6443bd37e..447e2ead37 100644
--- a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
@@ -1,3 +1,5 @@
+import { alias, not, gt, empty, notEmpty, equal } from "@ember/object/computed";
+import { inject } from "@ember/controller";
import DiscoveryController from "discourse/controllers/discovery";
import { queryParams } from "discourse/controllers/discovery-sortable";
import BulkTopicSelection from "discourse/mixins/bulk-topic-selection";
@@ -8,16 +10,14 @@ import TopicList from "discourse/models/topic-list";
import computed from "ember-addons/ember-computed-decorators";
const controllerOpts = {
- discovery: Ember.inject.controller(),
- discoveryTopics: Ember.inject.controller("discovery/topics"),
+ discovery: inject(),
+ discoveryTopics: inject("discovery/topics"),
period: null,
- canStar: Ember.computed.alias("currentUser.id"),
- showTopicPostBadges: Ember.computed.not("discoveryTopics.new"),
- redirectedReason: Ember.computed.alias(
- "currentUser.redirected_to_top.reason"
- ),
+ canStar: alias("currentUser.id"),
+ showTopicPostBadges: not("discoveryTopics.new"),
+ redirectedReason: alias("currentUser.redirected_to_top.reason"),
order: "default",
ascending: false,
@@ -117,16 +117,16 @@ const controllerOpts = {
);
},
- hasTopics: Ember.computed.gt("model.topics.length", 0),
- allLoaded: Ember.computed.empty("model.more_topics_url"),
+ hasTopics: gt("model.topics.length", 0),
+ allLoaded: empty("model.more_topics_url"),
latest: endWith("model.filter", "latest"),
new: endWith("model.filter", "new"),
- top: Ember.computed.notEmpty("period"),
- yearly: Ember.computed.equal("period", "yearly"),
- quarterly: Ember.computed.equal("period", "quarterly"),
- monthly: Ember.computed.equal("period", "monthly"),
- weekly: Ember.computed.equal("period", "weekly"),
- daily: Ember.computed.equal("period", "daily"),
+ top: notEmpty("period"),
+ yearly: equal("period", "yearly"),
+ quarterly: equal("period", "quarterly"),
+ monthly: equal("period", "monthly"),
+ weekly: equal("period", "weekly"),
+ daily: equal("period", "daily"),
@computed("allLoaded", "model.topics.length")
footerMessage(allLoaded, topicsLength) {
diff --git a/app/assets/javascripts/discourse/controllers/edit-category.js.es6 b/app/assets/javascripts/discourse/controllers/edit-category.js.es6
index 381292baaa..87c1378ffe 100644
--- a/app/assets/javascripts/discourse/controllers/edit-category.js.es6
+++ b/app/assets/javascripts/discourse/controllers/edit-category.js.es6
@@ -1,3 +1,5 @@
+import { isEmpty } from "@ember/utils";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import DiscourseURL from "discourse/lib/url";
import { extractError } from "discourse/lib/ajax-error";
@@ -7,7 +9,7 @@ import {
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
selectedTab: null,
saving: false,
deleting: false,
@@ -30,7 +32,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
@observes("model.description")
changeSize() {
- if (!Ember.isEmpty(this.get("model.description"))) {
+ if (!isEmpty(this.get("model.description"))) {
this.set("modal.modalClass", "edit-category-modal full");
} else {
this.set("modal.modalClass", "edit-category-modal small");
diff --git a/app/assets/javascripts/discourse/controllers/edit-topic-timer.js.es6 b/app/assets/javascripts/discourse/controllers/edit-topic-timer.js.es6
index d90ca5cbd4..7dc26c632c 100644
--- a/app/assets/javascripts/discourse/controllers/edit-topic-timer.js.es6
+++ b/app/assets/javascripts/discourse/controllers/edit-topic-timer.js.es6
@@ -1,7 +1,10 @@
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import TopicTimer from "discourse/models/topic-timer";
import { popupAjaxError } from "discourse/lib/ajax-error";
+import { setProperties } from "@ember/object";
export const CLOSE_STATUS_TYPE = "close";
export const OPEN_STATUS_TYPE = "open";
@@ -10,7 +13,7 @@ export const DELETE_STATUS_TYPE = "delete";
export const REMINDER_TYPE = "reminder";
export const BUMP_TYPE = "bump";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
isPublic: "true",
@@ -76,7 +79,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
if (time) {
this.send("closeModal");
- Ember.setProperties(this.topicTimer, {
+ setProperties(this.topicTimer, {
execute_at: result.execute_at,
duration: result.duration,
category_id: result.category_id
@@ -86,7 +89,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
} else {
const topicTimer =
this.isPublic === "true" ? "topic_timer" : "private_topic_timer";
- this.set(`model.${topicTimer}`, Ember.Object.create({}));
+ this.set(`model.${topicTimer}`, EmberObject.create({}));
this.setProperties({
selection: null
diff --git a/app/assets/javascripts/discourse/controllers/email-login.js.es6 b/app/assets/javascripts/discourse/controllers/email-login.js.es6
index d062144afe..78ab74f239 100644
--- a/app/assets/javascripts/discourse/controllers/email-login.js.es6
+++ b/app/assets/javascripts/discourse/controllers/email-login.js.es6
@@ -1,3 +1,4 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
import { ajax } from "discourse/lib/ajax";
@@ -5,7 +6,7 @@ import DiscourseURL from "discourse/lib/url";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { getWebauthnCredential } from "discourse/lib/webauthn";
-export default Ember.Controller.extend({
+export default Controller.extend({
lockImageUrl: Discourse.getURL("/images/lock.svg"),
@computed("model")
diff --git a/app/assets/javascripts/discourse/controllers/exception.js.es6 b/app/assets/javascripts/discourse/controllers/exception.js.es6
index 6b341b155a..7967f2d24a 100644
--- a/app/assets/javascripts/discourse/controllers/exception.js.es6
+++ b/app/assets/javascripts/discourse/controllers/exception.js.es6
@@ -1,3 +1,6 @@
+import { equal, gte, none, alias } from "@ember/object/computed";
+import { schedule } from "@ember/runloop";
+import Controller from "@ember/controller";
import {
on,
default as computed
@@ -26,7 +29,7 @@ const ButtonBackBright = {
};
// The controller for the nice error page
-export default Ember.Controller.extend({
+export default Controller.extend({
thrown: null,
lastTransition: null,
@@ -41,10 +44,10 @@ export default Ember.Controller.extend({
return false;
},
- isNotFound: Ember.computed.equal("thrown.status", 404),
- isForbidden: Ember.computed.equal("thrown.status", 403),
- isServer: Ember.computed.gte("thrown.status", 500),
- isUnknown: Ember.computed.none("isNetwork", "isServer"),
+ isNotFound: equal("thrown.status", 404),
+ isForbidden: equal("thrown.status", 403),
+ isServer: gte("thrown.status", 500),
+ isUnknown: none("isNetwork", "isServer"),
// TODO
// make ajax requests to /srv/status with exponential backoff
@@ -73,7 +76,7 @@ export default Ember.Controller.extend({
}
},
- requestUrl: Ember.computed.alias("thrown.requestedUrl"),
+ requestUrl: alias("thrown.requestedUrl"),
@computed("networkFixed", "isNetwork", "isServer", "isUnknown")
desc() {
@@ -112,7 +115,7 @@ export default Ember.Controller.extend({
tryLoading() {
this.set("loading", true);
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
this.lastTransition.retry();
this.set("loading", false);
});
diff --git a/app/assets/javascripts/discourse/controllers/explain-reviewable.js.es6 b/app/assets/javascripts/discourse/controllers/explain-reviewable.js.es6
index 49e57228a6..268958e105 100644
--- a/app/assets/javascripts/discourse/controllers/explain-reviewable.js.es6
+++ b/app/assets/javascripts/discourse/controllers/explain-reviewable.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: null,
reviewableExplanation: null,
diff --git a/app/assets/javascripts/discourse/controllers/feature-topic.js.es6 b/app/assets/javascripts/discourse/controllers/feature-topic.js.es6
index 9709b21c48..48ca403722 100644
--- a/app/assets/javascripts/discourse/controllers/feature-topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/feature-topic.js.es6
@@ -1,11 +1,13 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { categoryLinkHTML } from "discourse/helpers/category-link";
import computed from "ember-addons/ember-computed-decorators";
import InputValidation from "discourse/models/input-validation";
-export default Ember.Controller.extend(ModalFunctionality, {
- topicController: Ember.inject.controller("topic"),
+export default Controller.extend(ModalFunctionality, {
+ topicController: inject("topic"),
loading: true,
pinnedInCategoryCount: 0,
diff --git a/app/assets/javascripts/discourse/controllers/flag.js.es6 b/app/assets/javascripts/discourse/controllers/flag.js.es6
index bcfbb5e325..8f3c49ebc5 100644
--- a/app/assets/javascripts/discourse/controllers/flag.js.es6
+++ b/app/assets/javascripts/discourse/controllers/flag.js.es6
@@ -1,3 +1,6 @@
+import { not } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import ActionSummary from "discourse/models/action-summary";
import { MAX_MESSAGE_LENGTH } from "discourse/models/post-action-type";
@@ -5,7 +8,7 @@ import computed from "ember-addons/ember-computed-decorators";
import optionalService from "discourse/lib/optional-service";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
adminTools: optionalService(),
userDetails: null,
selected: null,
@@ -57,7 +60,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
return flagsAvailable;
} else {
// flagging topic
- let lookup = Ember.Object.create();
+ let lookup = EmberObject.create();
let model = this.model;
model.get("actions_summary").forEach(a => {
a.flagTopic = model;
@@ -97,7 +100,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
return true;
},
- submitDisabled: Ember.computed.not("submitEnabled"),
+ submitDisabled: not("submitEnabled"),
// Staff accounts can "take action"
@computed("flagTopic", "selected.is_custom_flag")
@@ -154,6 +157,13 @@ export default Ember.Controller.extend(ModalFunctionality, {
params = $.extend(params, opts);
}
+ this.appEvents.trigger(
+ this.flagTopic ? "topic:flag-created" : "post:flag-created",
+ this.model,
+ postAction,
+ params
+ );
+
this.send("hideModal");
postAction
diff --git a/app/assets/javascripts/discourse/controllers/forgot-password.js.es6 b/app/assets/javascripts/discourse/controllers/forgot-password.js.es6
index 288ffa8ba8..ae5d53679d 100644
--- a/app/assets/javascripts/discourse/controllers/forgot-password.js.es6
+++ b/app/assets/javascripts/discourse/controllers/forgot-password.js.es6
@@ -1,16 +1,18 @@
+import { isEmpty } from "@ember/utils";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { escapeExpression } from "discourse/lib/utilities";
import { extractError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
offerHelp: null,
helpSeen: false,
@computed("accountEmailOrUsername", "disabled")
submitDisabled(accountEmailOrUsername, disabled) {
- return Ember.isEmpty((accountEmailOrUsername || "").trim()) || disabled;
+ return isEmpty((accountEmailOrUsername || "").trim()) || disabled;
},
onShow() {
diff --git a/app/assets/javascripts/discourse/controllers/full-page-search.js.es6 b/app/assets/javascripts/discourse/controllers/full-page-search.js.es6
index c7175a47fd..0b37bead27 100644
--- a/app/assets/javascripts/discourse/controllers/full-page-search.js.es6
+++ b/app/assets/javascripts/discourse/controllers/full-page-search.js.es6
@@ -1,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import { or } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import {
translateResults,
@@ -12,8 +16,8 @@ import {
import Category from "discourse/models/category";
import { escapeExpression } from "discourse/lib/utilities";
import { setTransient } from "discourse/lib/page-tracker";
-import { iconHTML } from "discourse-common/lib/icon-library";
import Composer from "discourse/models/composer";
+import { scrollTop } from "discourse/mixins/scroll-top";
const SortOrders = [
{ name: I18n.t("search.relevance"), id: 0 },
@@ -24,9 +28,9 @@ const SortOrders = [
];
const PAGE_LIMIT = 10;
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
- composer: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
+ composer: inject(),
bulkSelectEnabled: null,
loading: false,
@@ -50,7 +54,7 @@ export default Ember.Controller.extend({
@computed("q")
hasAutofocus(q) {
- return Ember.isEmpty(q);
+ return isEmpty(q);
},
@computed("q")
@@ -194,17 +198,12 @@ export default Ember.Controller.extend({
return this.currentUser && userCanCreateTopic;
},
- @computed("expanded")
- searchAdvancedIcon(expanded) {
- return iconHTML(expanded ? "caret-down" : "caret-right");
- },
-
@computed("page")
isLastPage(page) {
return page === PAGE_LIMIT;
},
- searchButtonDisabled: Ember.computed.or("searching", "loading"),
+ searchButtonDisabled: or("searching", "loading"),
_search() {
if (this.searching) {
@@ -224,6 +223,7 @@ export default Ember.Controller.extend({
this.set("bulkSelectEnabled", false);
this.selected.clear();
this.set("searching", true);
+ scrollTop();
} else {
this.set("loading", true);
}
@@ -285,7 +285,7 @@ export default Ember.Controller.extend({
}
this.composer.open({
action: Composer.CREATE_TOPIC,
- draftKey: Composer.CREATE_TOPIC,
+ draftKey: Composer.NEW_TOPIC_KEY,
topicCategory
});
},
diff --git a/app/assets/javascripts/discourse/controllers/grant-badge.js.es6 b/app/assets/javascripts/discourse/controllers/grant-badge.js.es6
index 13757e678e..287b6a6994 100644
--- a/app/assets/javascripts/discourse/controllers/grant-badge.js.es6
+++ b/app/assets/javascripts/discourse/controllers/grant-badge.js.es6
@@ -1,86 +1,85 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { extractError } from "discourse/lib/ajax-error";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import GrantBadgeController from "discourse/mixins/grant-badge-controller";
import Badge from "discourse/models/badge";
import UserBadge from "discourse/models/user-badge";
+import { all } from "rsvp";
-export default Ember.Controller.extend(
- ModalFunctionality,
- GrantBadgeController,
- {
- topicController: Ember.inject.controller("topic"),
- loading: true,
- saving: false,
- selectedBadgeId: null,
+export default Controller.extend(ModalFunctionality, GrantBadgeController, {
+ topicController: inject("topic"),
+ loading: true,
+ saving: false,
+ selectedBadgeId: null,
- init() {
- this._super(...arguments);
+ init() {
+ this._super(...arguments);
- this.allBadges = [];
- this.userBadges = [];
- },
+ this.allBadges = [];
+ this.userBadges = [];
+ },
- @computed("topicController.selectedPosts")
- post() {
- return this.get("topicController.selectedPosts")[0];
- },
+ @computed("topicController.selectedPosts")
+ post() {
+ return this.get("topicController.selectedPosts")[0];
+ },
- @computed("post")
- badgeReason(post) {
- const url = post.get("url");
- const protocolAndHost =
- window.location.protocol + "//" + window.location.host;
+ @computed("post")
+ badgeReason(post) {
+ const url = post.get("url");
+ const protocolAndHost =
+ window.location.protocol + "//" + window.location.host;
- return url.indexOf("/") === 0 ? protocolAndHost + url : url;
- },
+ return url.indexOf("/") === 0 ? protocolAndHost + url : url;
+ },
- @computed("saving", "selectedBadgeGrantable")
- buttonDisabled(saving, selectedBadgeGrantable) {
- return saving || !selectedBadgeGrantable;
- },
+ @computed("saving", "selectedBadgeGrantable")
+ buttonDisabled(saving, selectedBadgeGrantable) {
+ return saving || !selectedBadgeGrantable;
+ },
- onShow() {
- this.set("loading", true);
+ onShow() {
+ this.set("loading", true);
- Ember.RSVP.all([
- Badge.findAll(),
- UserBadge.findByUsername(this.get("post.username"))
- ]).then(([allBadges, userBadges]) => {
- this.setProperties({
- allBadges: allBadges,
- userBadges: userBadges,
- loading: false
- });
+ all([
+ Badge.findAll(),
+ UserBadge.findByUsername(this.get("post.username"))
+ ]).then(([allBadges, userBadges]) => {
+ this.setProperties({
+ allBadges: allBadges,
+ userBadges: userBadges,
+ loading: false
});
- },
+ });
+ },
- actions: {
- grantBadge() {
- this.set("saving", true);
+ actions: {
+ grantBadge() {
+ this.set("saving", true);
- this.grantBadge(
- this.selectedBadgeId,
- this.get("post.username"),
- this.badgeReason
+ this.grantBadge(
+ this.selectedBadgeId,
+ this.get("post.username"),
+ this.badgeReason
+ )
+ .then(
+ newBadge => {
+ this.set("selectedBadgeId", null);
+ this.flash(
+ I18n.t("badges.successfully_granted", {
+ username: this.get("post.username"),
+ badge: newBadge.get("badge.name")
+ }),
+ "success"
+ );
+ },
+ error => {
+ this.flash(extractError(error), "error");
+ }
)
- .then(
- newBadge => {
- this.set("selectedBadgeId", null);
- this.flash(
- I18n.t("badges.successfully_granted", {
- username: this.get("post.username"),
- badge: newBadge.get("badge.name")
- }),
- "success"
- );
- },
- error => {
- this.flash(extractError(error), "error");
- }
- )
- .finally(() => this.set("saving", false));
- }
+ .finally(() => this.set("saving", false));
}
}
-);
+});
diff --git a/app/assets/javascripts/discourse/controllers/group-activity-posts.js.es6 b/app/assets/javascripts/discourse/controllers/group-activity-posts.js.es6
index 3e4454ce0e..ed648a3dec 100644
--- a/app/assets/javascripts/discourse/controllers/group-activity-posts.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-activity-posts.js.es6
@@ -1,10 +1,12 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { observes } from "ember-addons/ember-computed-decorators";
import { fmt } from "discourse/lib/computed";
-export default Ember.Controller.extend({
- group: Ember.inject.controller(),
- groupActivity: Ember.inject.controller(),
- application: Ember.inject.controller(),
+export default Controller.extend({
+ group: inject(),
+ groupActivity: inject(),
+ application: inject(),
canLoadMore: true,
loading: false,
emptyText: fmt("type", "groups.empty.%@"),
diff --git a/app/assets/javascripts/discourse/controllers/group-activity-topics.js.es6 b/app/assets/javascripts/discourse/controllers/group-activity-topics.js.es6
index 2a559a196c..6d922b754e 100644
--- a/app/assets/javascripts/discourse/controllers/group-activity-topics.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-activity-topics.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Controller.extend({
+import Controller from "@ember/controller";
+export default Controller.extend({
actions: {
loadMore() {
this.model.loadMore();
diff --git a/app/assets/javascripts/discourse/controllers/group-activity.js.es6 b/app/assets/javascripts/discourse/controllers/group-activity.js.es6
index 26fa94835a..5c48daee43 100644
--- a/app/assets/javascripts/discourse/controllers/group-activity.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-activity.js.es6
@@ -1,4 +1,6 @@
-export default Ember.Controller.extend({
- router: Ember.inject.service(),
+import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
+export default Controller.extend({
+ router: service(),
queryParams: ["category_id"]
});
diff --git a/app/assets/javascripts/discourse/controllers/group-add-members.js.es6 b/app/assets/javascripts/discourse/controllers/group-add-members.js.es6
index 6e478fe3d8..53c1327c42 100644
--- a/app/assets/javascripts/discourse/controllers/group-add-members.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-add-members.js.es6
@@ -1,8 +1,10 @@
+import { isEmpty } from "@ember/utils";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { extractError } from "discourse/lib/ajax-error";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
setAsOwner: false,
@@ -17,7 +19,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
const model = this.model;
const usernames = model.get("usernames");
- if (Ember.isEmpty(usernames)) {
+ if (isEmpty(usernames)) {
return;
}
let promise;
diff --git a/app/assets/javascripts/discourse/controllers/group-bulk-add.js.es6 b/app/assets/javascripts/discourse/controllers/group-bulk-add.js.es6
index 716347d4c6..bef9d535f4 100644
--- a/app/assets/javascripts/discourse/controllers/group-bulk-add.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-bulk-add.js.es6
@@ -1,14 +1,16 @@
+import { isEmpty } from "@ember/utils";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { extractError } from "discourse/lib/ajax-error";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { ajax } from "discourse/lib/ajax";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
@computed("input", "loading", "result")
disableAddButton(input, loading, result) {
- return loading || Ember.isEmpty(input) || input.length <= 0 || result;
+ return loading || isEmpty(input) || input.length <= 0 || result;
},
actions: {
diff --git a/app/assets/javascripts/discourse/controllers/group-index.js.es6 b/app/assets/javascripts/discourse/controllers/group-index.js.es6
index 690997aa54..2cc94f9f4e 100644
--- a/app/assets/javascripts/discourse/controllers/group-index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-index.js.es6
@@ -1,3 +1,6 @@
+import { alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import Group from "discourse/models/group";
import {
@@ -6,18 +9,18 @@ import {
} from "ember-addons/ember-computed-decorators";
import debounce from "discourse/lib/debounce";
-export default Ember.Controller.extend({
+export default Controller.extend({
queryParams: ["order", "desc", "filter"],
order: "",
desc: null,
loading: false,
limit: null,
offset: null,
- isOwner: Ember.computed.alias("model.is_group_owner"),
+ isOwner: alias("model.is_group_owner"),
showActions: false,
filter: null,
filterInput: null,
- application: Ember.inject.controller(),
+ application: inject(),
@observes("filterInput")
_setFilter: debounce(function() {
diff --git a/app/assets/javascripts/discourse/controllers/group-manage-logs.js.es6 b/app/assets/javascripts/discourse/controllers/group-manage-logs.js.es6
index 22ee01cff5..f5c3ba48f3 100644
--- a/app/assets/javascripts/discourse/controllers/group-manage-logs.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-manage-logs.js.es6
@@ -1,17 +1,20 @@
+import { inject } from "@ember/controller";
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
- group: Ember.inject.controller(),
+export default Controller.extend({
+ group: inject(),
loading: false,
offset: 0,
- application: Ember.inject.controller(),
+ application: inject(),
init() {
this._super(...arguments);
- this.set("filters", Ember.Object.create());
+ this.set("filters", EmberObject.create());
},
@computed(
@@ -51,7 +54,7 @@ export default Ember.Controller.extend({
reset() {
this.setProperties({
offset: 0,
- filters: Ember.Object.create()
+ filters: EmberObject.create()
});
},
diff --git a/app/assets/javascripts/discourse/controllers/group-manage-profile.js.es6 b/app/assets/javascripts/discourse/controllers/group-manage-profile.js.es6
index e316e97fad..719745dfa3 100644
--- a/app/assets/javascripts/discourse/controllers/group-manage-profile.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-manage-profile.js.es6
@@ -1,3 +1,4 @@
-export default Ember.Controller.extend({
+import Controller from "@ember/controller";
+export default Controller.extend({
saving: null
});
diff --git a/app/assets/javascripts/discourse/controllers/group-manage.js.es6 b/app/assets/javascripts/discourse/controllers/group-manage.js.es6
index 795627c3cb..dab05b6dbc 100644
--- a/app/assets/javascripts/discourse/controllers/group-manage.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-manage.js.es6
@@ -1,7 +1,9 @@
+import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
- router: Ember.inject.service(),
+export default Controller.extend({
+ router: service(),
@computed("model.automatic")
tabs(automatic) {
diff --git a/app/assets/javascripts/discourse/controllers/group-messages.js.es6 b/app/assets/javascripts/discourse/controllers/group-messages.js.es6
index cda126a2e2..a422a1f33c 100644
--- a/app/assets/javascripts/discourse/controllers/group-messages.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-messages.js.es6
@@ -1,3 +1,5 @@
-export default Ember.Controller.extend({
- router: Ember.inject.service()
+import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
+export default Controller.extend({
+ router: service()
});
diff --git a/app/assets/javascripts/discourse/controllers/group-requests.js.es6 b/app/assets/javascripts/discourse/controllers/group-requests.js.es6
index 178db75758..246fd0cf9a 100644
--- a/app/assets/javascripts/discourse/controllers/group-requests.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group-requests.js.es6
@@ -1,3 +1,5 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import Group from "discourse/models/group";
@@ -7,7 +9,7 @@ import {
} from "ember-addons/ember-computed-decorators";
import debounce from "discourse/lib/debounce";
-export default Ember.Controller.extend({
+export default Controller.extend({
queryParams: ["order", "desc", "filter"],
order: "",
desc: null,
@@ -16,7 +18,7 @@ export default Ember.Controller.extend({
offset: null,
filter: null,
filterInput: null,
- application: Ember.inject.controller(),
+ application: inject(),
@observes("filterInput")
_setFilter: debounce(function() {
diff --git a/app/assets/javascripts/discourse/controllers/group.js.es6 b/app/assets/javascripts/discourse/controllers/group.js.es6
index f6a44552aa..322e7ab12c 100644
--- a/app/assets/javascripts/discourse/controllers/group.js.es6
+++ b/app/assets/javascripts/discourse/controllers/group.js.es6
@@ -1,6 +1,9 @@
+import EmberObject from "@ember/object";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
-const Tab = Ember.Object.extend({
+const Tab = EmberObject.extend({
init() {
this._super(...arguments);
let name = this.name;
@@ -9,8 +12,8 @@ const Tab = Ember.Object.extend({
}
});
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
counts: null,
showing: "members",
destroying: null,
diff --git a/app/assets/javascripts/discourse/controllers/groups-index.js.es6 b/app/assets/javascripts/discourse/controllers/groups-index.js.es6
index 1c6a824ded..a466572b26 100644
--- a/app/assets/javascripts/discourse/controllers/groups-index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/groups-index.js.es6
@@ -1,11 +1,13 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import debounce from "discourse/lib/debounce";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
queryParams: ["order", "asc", "filter", "type"],
order: null,
asc: null,
diff --git a/app/assets/javascripts/discourse/controllers/groups-new.js.es6 b/app/assets/javascripts/discourse/controllers/groups-new.js.es6
index 293beffd53..f93c08959d 100644
--- a/app/assets/javascripts/discourse/controllers/groups-new.js.es6
+++ b/app/assets/javascripts/discourse/controllers/groups-new.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
saving: null,
actions: {
diff --git a/app/assets/javascripts/discourse/controllers/history.js.es6 b/app/assets/javascripts/discourse/controllers/history.js.es6
index 53627c157f..69ea502d41 100644
--- a/app/assets/javascripts/discourse/controllers/history.js.es6
+++ b/app/assets/javascripts/discourse/controllers/history.js.es6
@@ -1,3 +1,5 @@
+import { alias, gt, not, or, equal } from "@ember/object/computed";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { categoryBadgeHTML } from "discourse/helpers/category-link";
import computed from "ember-addons/ember-computed-decorators";
@@ -20,7 +22,7 @@ function customTagArray(fieldName) {
}
// This controller handles displaying of history
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: true,
viewMode: "side_by_side",
@@ -31,12 +33,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
}
},
- previousFeaturedLink: Ember.computed.alias(
- "model.featured_link_changes.previous"
- ),
- currentFeaturedLink: Ember.computed.alias(
- "model.featured_link_changes.current"
- ),
+ previousFeaturedLink: alias("model.featured_link_changes.previous"),
+ currentFeaturedLink: alias("model.featured_link_changes.current"),
previousTagChanges: customTagArray("model.tags_changes.previous"),
currentTagChanges: customTagArray("model.tags_changes.current"),
@@ -118,7 +116,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
return prev && current > prev;
},
- displayRevisions: Ember.computed.gt("model.version_count", 2),
+ displayRevisions: gt("model.version_count", 2),
displayGoToFirst: propertyGreaterThan(
"model.current_revision",
"model.first_revision"
@@ -132,15 +130,15 @@ export default Ember.Controller.extend(ModalFunctionality, {
"model.next_revision"
),
- hideGoToFirst: Ember.computed.not("displayGoToFirst"),
- hideGoToPrevious: Ember.computed.not("displayGoToPrevious"),
- hideGoToNext: Ember.computed.not("displayGoToNext"),
- hideGoToLast: Ember.computed.not("displayGoToLast"),
+ hideGoToFirst: not("displayGoToFirst"),
+ hideGoToPrevious: not("displayGoToPrevious"),
+ hideGoToNext: not("displayGoToNext"),
+ hideGoToLast: not("displayGoToLast"),
- loadFirstDisabled: Ember.computed.or("loading", "hideGoToFirst"),
- loadPreviousDisabled: Ember.computed.or("loading", "hideGoToPrevious"),
- loadNextDisabled: Ember.computed.or("loading", "hideGoToNext"),
- loadLastDisabled: Ember.computed.or("loading", "hideGoToLast"),
+ loadFirstDisabled: or("loading", "hideGoToFirst"),
+ loadPreviousDisabled: or("loading", "hideGoToPrevious"),
+ loadNextDisabled: or("loading", "hideGoToNext"),
+ loadLastDisabled: or("loading", "hideGoToLast"),
@computed("model.previous_hidden")
displayShow(prevHidden) {
@@ -172,10 +170,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
return this.currentUser && this.currentUser.get("staff");
},
- isEitherRevisionHidden: Ember.computed.or(
- "model.previous_hidden",
- "model.current_hidden"
- ),
+ isEitherRevisionHidden: or("model.previous_hidden", "model.current_hidden"),
@computed("model.previous_hidden", "model.current_hidden", "displayingInline")
hiddenClasses(prevHidden, currentHidden, displayingInline) {
@@ -193,12 +188,9 @@ export default Ember.Controller.extend(ModalFunctionality, {
}
},
- displayingInline: Ember.computed.equal("viewMode", "inline"),
- displayingSideBySide: Ember.computed.equal("viewMode", "side_by_side"),
- displayingSideBySideMarkdown: Ember.computed.equal(
- "viewMode",
- "side_by_side_markdown"
- ),
+ displayingInline: equal("viewMode", "inline"),
+ displayingSideBySide: equal("viewMode", "side_by_side"),
+ displayingSideBySideMarkdown: equal("viewMode", "side_by_side_markdown"),
@computed("displayingInline")
inlineClass(displayingInline) {
diff --git a/app/assets/javascripts/discourse/controllers/ignore-duration-with-username.js.es6 b/app/assets/javascripts/discourse/controllers/ignore-duration-with-username.js.es6
index 6ba026a1b8..491c496df7 100644
--- a/app/assets/javascripts/discourse/controllers/ignore-duration-with-username.js.es6
+++ b/app/assets/javascripts/discourse/controllers/ignore-duration-with-username.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { popupAjaxError } from "discourse/lib/ajax-error";
import User from "discourse/models/user";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
ignoredUntil: null,
ignoredUsername: null,
diff --git a/app/assets/javascripts/discourse/controllers/ignore-duration.js.es6 b/app/assets/javascripts/discourse/controllers/ignore-duration.js.es6
index 574f69e373..c78b73cbb3 100644
--- a/app/assets/javascripts/discourse/controllers/ignore-duration.js.es6
+++ b/app/assets/javascripts/discourse/controllers/ignore-duration.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
ignoredUntil: null,
actions: {
diff --git a/app/assets/javascripts/discourse/controllers/insert-hyperlink.js.es6 b/app/assets/javascripts/discourse/controllers/insert-hyperlink.js.es6
index d4f15d95cf..b04499456b 100644
--- a/app/assets/javascripts/discourse/controllers/insert-hyperlink.js.es6
+++ b/app/assets/javascripts/discourse/controllers/insert-hyperlink.js.es6
@@ -1,15 +1,145 @@
+import { isEmpty } from "@ember/utils";
+import { debounce } from "@ember/runloop";
+import { cancel } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
+import { searchForTerm } from "discourse/lib/search";
-export default Ember.Controller.extend(ModalFunctionality, {
- linkUrl: "",
- linkText: "",
+export default Controller.extend(ModalFunctionality, {
+ _debounced: null,
+ _activeSearch: null,
onShow() {
- Ember.run.next(() =>
- $(this)
- .find("input.link-url")
- .focus()
- );
+ this.setProperties({
+ linkUrl: "",
+ linkText: "",
+ searchResults: [],
+ searchLoading: false,
+ selectedRow: -1
+ });
+
+ scheduleOnce("afterRender", () => {
+ const element = document.querySelector(".insert-link");
+
+ element.addEventListener("keydown", e => this.keyDown(e));
+
+ element
+ .closest(".modal-inner-container")
+ .addEventListener("mousedown", e => this.mouseDown(e));
+
+ document.querySelector("input.link-url").focus();
+ });
+ },
+
+ keyDown(e) {
+ switch (e.which) {
+ case 40:
+ this.highlightRow(e, "down");
+ break;
+ case 38:
+ this.highlightRow(e, "up");
+ break;
+ case 13:
+ // override Enter behaviour when a row is selected
+ if (this.selectedRow > -1) {
+ const selected = document.querySelectorAll(
+ ".internal-link-results .search-link"
+ )[this.selectedRow];
+ this.selectLink(selected);
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ break;
+ case 27:
+ // Esc should cancel dropdown first
+ if (this.searchResults.length) {
+ this.set("searchResults", []);
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ break;
+ }
+ },
+
+ mouseDown(e) {
+ if (!e.target.closest(".inputs")) {
+ this.set("searchResults", []);
+ }
+ },
+
+ highlightRow(e, direction) {
+ const index =
+ direction === "down" ? this.selectedRow + 1 : this.selectedRow - 1;
+
+ if (index > -1 && index < this.searchResults.length) {
+ document
+ .querySelectorAll(".internal-link-results .search-link")
+ [index].focus();
+ this.set("selectedRow", index);
+ } else {
+ this.set("selectedRow", -1);
+ document.querySelector("input.link-url").focus();
+ }
+
+ e.preventDefault();
+ },
+
+ selectLink(el) {
+ this.setProperties({
+ linkUrl: el.href,
+ searchResults: [],
+ selectedRow: -1
+ });
+
+ if (!this.linkText && el.dataset.title) {
+ this.set("linkText", el.dataset.title);
+ }
+
+ document.querySelector("input.link-text").focus();
+ },
+
+ triggerSearch() {
+ if (this.linkUrl.length > 3 && this.linkUrl.indexOf("http") === -1) {
+ this.set("searchLoading", true);
+ this._activeSearch = searchForTerm(this.linkUrl, {
+ typeFilter: "topic"
+ });
+ this._activeSearch
+ .then(results => {
+ if (results && results.topics && results.topics.length > 0) {
+ this.set("searchResults", results.topics);
+ } else {
+ this.set("searchResults", []);
+ }
+ })
+ .finally(() => {
+ this.set("searchLoading", false);
+ this._activeSearch = null;
+ });
+ } else {
+ this.abortSearch();
+ }
+ },
+
+ abortSearch() {
+ if (this._activeSearch) {
+ this._activeSearch.abort();
+ }
+ this.setProperties({
+ searchResults: [],
+ searchLoading: false
+ });
+ },
+
+ onClose() {
+ const element = document.querySelector(".insert-link");
+ element.removeEventListener("keydown", this.keyDown);
+ element
+ .closest(".modal-inner-container")
+ .removeEventListener("mousedown", this.mouseDown);
+
+ cancel(this._debounced);
},
actions: {
@@ -19,7 +149,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
origLink.indexOf("://") === -1 ? `http://${origLink}` : origLink;
const sel = this._lastSel;
- if (Ember.isEmpty(linkUrl)) {
+ if (isEmpty(linkUrl)) {
return;
}
@@ -35,12 +165,20 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.toolbarEvent.selectText(sel.start + 1, origLink.length);
}
}
- this.set("linkUrl", "");
- this.set("linkText", "");
this.send("closeModal");
},
cancel() {
this.send("closeModal");
+ },
+ linkClick(e) {
+ if (!e.metaKey && !e.ctrlKey) {
+ e.preventDefault();
+ e.stopPropagation();
+ this.selectLink(e.target.closest(".search-link"));
+ }
+ },
+ search() {
+ this._debounced = debounce(this, this.triggerSearch, 400);
}
}
});
diff --git a/app/assets/javascripts/discourse/controllers/invites-show.js.es6 b/app/assets/javascripts/discourse/controllers/invites-show.js.es6
index 2664a95bd7..1b1c99de7d 100644
--- a/app/assets/javascripts/discourse/controllers/invites-show.js.es6
+++ b/app/assets/javascripts/discourse/controllers/invites-show.js.es6
@@ -1,3 +1,6 @@
+import { isEmpty } from "@ember/utils";
+import { alias, notEmpty } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import getUrl from "discourse-common/lib/get-url";
import DiscourseURL from "discourse/lib/url";
@@ -8,16 +11,16 @@ import NameValidation from "discourse/mixins/name-validation";
import UserFieldsValidation from "discourse/mixins/user-fields-validation";
import { findAll as findLoginMethods } from "discourse/models/login-method";
-export default Ember.Controller.extend(
+export default Controller.extend(
PasswordValidation,
UsernameValidation,
NameValidation,
UserFieldsValidation,
{
- invitedBy: Ember.computed.alias("model.invited_by"),
- email: Ember.computed.alias("model.email"),
- accountUsername: Ember.computed.alias("model.username"),
- passwordRequired: Ember.computed.notEmpty("accountPassword"),
+ invitedBy: alias("model.invited_by"),
+ email: alias("model.email"),
+ accountUsername: alias("model.username"),
+ passwordRequired: notEmpty("accountPassword"),
successMessage: null,
errorMessage: null,
userFields: null,
@@ -66,7 +69,7 @@ export default Ember.Controller.extend(
submit() {
const userFields = this.userFields;
let userCustomFields = {};
- if (!Ember.isEmpty(userFields)) {
+ if (!isEmpty(userFields)) {
userFields.forEach(function(f) {
userCustomFields[f.get("field.id")] = f.get("value");
});
diff --git a/app/assets/javascripts/discourse/controllers/jump-to-post.js.es6 b/app/assets/javascripts/discourse/controllers/jump-to-post.js.es6
index 385db0406f..35981f39a7 100644
--- a/app/assets/javascripts/discourse/controllers/jump-to-post.js.es6
+++ b/app/assets/javascripts/discourse/controllers/jump-to-post.js.es6
@@ -1,15 +1,16 @@
+import { alias } from "@ember/object/computed";
+import { next } from "@ember/runloop";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
model: null,
postNumber: null,
postDate: null,
- filteredPostsCount: Ember.computed.alias(
- "topic.postStream.filteredPostsCount"
- ),
+ filteredPostsCount: alias("topic.postStream.filteredPostsCount"),
onShow() {
- Ember.run.next(() => $("#post-jump").focus());
+ next(() => $("#post-jump").focus());
},
actions: {
diff --git a/app/assets/javascripts/discourse/controllers/keyboard-shortcuts-help.js.es6 b/app/assets/javascripts/discourse/controllers/keyboard-shortcuts-help.js.es6
index 9520e6c8f8..9e1c216e13 100644
--- a/app/assets/javascripts/discourse/controllers/keyboard-shortcuts-help.js.es6
+++ b/app/assets/javascripts/discourse/controllers/keyboard-shortcuts-help.js.es6
@@ -1,3 +1,4 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
const KEY = "keyboard_shortcuts_help";
@@ -46,7 +47,7 @@ function buildShortcut(
return I18n.t(`${KEY}.${key}`, context);
}
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
onShow() {
this.set("modal.modalClass", "keyboard-shortcuts-modal");
},
diff --git a/app/assets/javascripts/discourse/controllers/login.js.es6 b/app/assets/javascripts/discourse/controllers/login.js.es6
index 7f0f5bdd33..19fbc21fb7 100644
--- a/app/assets/javascripts/discourse/controllers/login.js.es6
+++ b/app/assets/javascripts/discourse/controllers/login.js.es6
@@ -1,3 +1,10 @@
+import { isEmpty } from "@ember/utils";
+import { alias, or, readOnly } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { next } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import showModal from "discourse/lib/show-modal";
@@ -19,10 +26,10 @@ const AuthErrors = [
"not_allowed_from_ip_address"
];
-export default Ember.Controller.extend(ModalFunctionality, {
- createAccount: Ember.inject.controller(),
- forgotPassword: Ember.inject.controller(),
- application: Ember.inject.controller(),
+export default Controller.extend(ModalFunctionality, {
+ createAccount: inject(),
+ forgotPassword: inject(),
+ application: inject(),
loggingIn: false,
loggedIn: false,
@@ -33,7 +40,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
canLoginLocal: setting("enable_local_logins"),
canLoginLocalWithEmail: setting("enable_local_logins_via_email"),
- loginRequired: Ember.computed.alias("application.loginRequired"),
+ loginRequired: alias("application.loginRequired"),
secondFactorMethod: SECOND_FACTOR_METHODS.TOTP,
resetForm() {
@@ -81,14 +88,14 @@ export default Ember.Controller.extend(ModalFunctionality, {
return loggingIn ? "login.logging_in" : "login.title";
},
- loginDisabled: Ember.computed.or("loggingIn", "loggedIn"),
+ loginDisabled: or("loggingIn", "loggedIn"),
@computed("loggingIn", "application.canSignUp")
showSignupLink(loggingIn, canSignUp) {
return canSignUp && !loggingIn;
},
- showSpinner: Ember.computed.readOnly("loggingIn"),
+ showSpinner: readOnly("loggingIn"),
@computed("canLoginLocalWithEmail", "processingEmailLink")
showLoginWithEmailLink(canLoginLocalWithEmail, processingEmailLink) {
@@ -101,7 +108,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
return;
}
- if (Ember.isEmpty(this.loginName) || Ember.isEmpty(this.loginPassword)) {
+ if (isEmpty(this.loginName) || isEmpty(this.loginPassword)) {
this.flash(I18n.t("login.blank_username_or_password"), "error");
return;
}
@@ -147,7 +154,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
// only need to focus the 2FA input for TOTP
if (!this.showSecurityKey) {
- Ember.run.scheduleOnce("afterRender", () =>
+ scheduleOnce("afterRender", () =>
document
.getElementById("second-factor")
.querySelector("input")
@@ -267,7 +274,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
return;
}
- if (Ember.isEmpty(this.loginName)) {
+ if (isEmpty(this.loginName)) {
this.flash(I18n.t("login.blank_username"), "error");
return;
}
@@ -319,7 +326,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
const loginError = (errorMsg, className, callback) => {
showModal("login");
- Ember.run.next(() => {
+ next(() => {
if (callback) callback();
this.flash(errorMsg, className || "success");
});
@@ -376,7 +383,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
accountEmail: options.email,
accountUsername: options.username,
accountName: options.name,
- authOptions: Ember.Object.create(options)
+ authOptions: EmberObject.create(options)
});
showModal("createAccount");
diff --git a/app/assets/javascripts/discourse/controllers/modal.js.es6 b/app/assets/javascripts/discourse/controllers/modal.js.es6
index 77c79b724a..cf6c4e3aa2 100644
--- a/app/assets/javascripts/discourse/controllers/modal.js.es6
+++ b/app/assets/javascripts/discourse/controllers/modal.js.es6
@@ -1 +1,2 @@
-export default Ember.Controller.extend();
+import Controller from "@ember/controller";
+export default Controller.extend();
diff --git a/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6 b/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6
index fa41654818..c8934801cb 100644
--- a/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6
@@ -1,21 +1,26 @@
+import { isEmpty } from "@ember/utils";
+import { alias, equal } from "@ember/object/computed";
+import { next } from "@ember/runloop";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { movePosts, mergeTopic } from "discourse/models/topic";
import DiscourseURL from "discourse/lib/url";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { extractError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
topicName: null,
saving: false,
categoryId: null,
tags: null,
- canAddTags: Ember.computed.alias("site.can_create_tag"),
- canTagMessages: Ember.computed.alias("site.can_tag_pms"),
+ canAddTags: alias("site.can_create_tag"),
+ canTagMessages: alias("site.can_tag_pms"),
selectedTopicId: null,
- newTopic: Ember.computed.equal("selection", "new_topic"),
- existingTopic: Ember.computed.equal("selection", "existing_topic"),
- newMessage: Ember.computed.equal("selection", "new_message"),
- existingMessage: Ember.computed.equal("selection", "existing_message"),
+ newTopic: equal("selection", "new_topic"),
+ existingTopic: equal("selection", "existing_topic"),
+ newMessage: equal("selection", "new_message"),
+ existingMessage: equal("selection", "existing_message"),
participants: null,
init() {
@@ -36,18 +41,14 @@ export default Ember.Controller.extend(ModalFunctionality, {
];
},
- topicController: Ember.inject.controller("topic"),
- selectedPostsCount: Ember.computed.alias(
- "topicController.selectedPostsCount"
- ),
- selectedAllPosts: Ember.computed.alias("topicController.selectedAllPosts"),
- selectedPosts: Ember.computed.alias("topicController.selectedPosts"),
+ topicController: inject("topic"),
+ selectedPostsCount: alias("topicController.selectedPostsCount"),
+ selectedAllPosts: alias("topicController.selectedAllPosts"),
+ selectedPosts: alias("topicController.selectedPosts"),
@computed("saving", "selectedTopicId", "topicName")
buttonDisabled(saving, selectedTopicId, topicName) {
- return (
- saving || (Ember.isEmpty(selectedTopicId) && Ember.isEmpty(topicName))
- );
+ return saving || (isEmpty(selectedTopicId) && isEmpty(topicName));
},
@computed(
@@ -90,7 +91,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
);
} else if (!this.canSplitTopic) {
this.set("selection", "existing_topic");
- Ember.run.next(() => $("#choose-topic-title").focus());
+ next(() => $("#choose-topic-title").focus());
}
},
diff --git a/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6 b/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6
index ee6066f186..216ca0448f 100644
--- a/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6
+++ b/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6
@@ -1,8 +1,9 @@
+import { inject } from "@ember/controller";
import NavigationDefaultController from "discourse/controllers/navigation/default";
import computed from "ember-addons/ember-computed-decorators";
export default NavigationDefaultController.extend({
- discoveryCategories: Ember.inject.controller("discovery/categories"),
+ discoveryCategories: inject("discovery/categories"),
@computed("discoveryCategories.model", "discoveryCategories.model.draft")
draft() {
diff --git a/app/assets/javascripts/discourse/controllers/navigation/category.js.es6 b/app/assets/javascripts/discourse/controllers/navigation/category.js.es6
index a54af35e2a..1b13265576 100644
--- a/app/assets/javascripts/discourse/controllers/navigation/category.js.es6
+++ b/app/assets/javascripts/discourse/controllers/navigation/category.js.es6
@@ -1,8 +1,9 @@
+import { none, and } from "@ember/object/computed";
import NavigationDefaultController from "discourse/controllers/navigation/default";
export default NavigationDefaultController.extend({
- showingParentCategory: Ember.computed.none("category.parentCategory"),
- showingSubcategoryList: Ember.computed.and(
+ showingParentCategory: none("category.parentCategory"),
+ showingSubcategoryList: and(
"category.show_subcategory_list",
"showingParentCategory"
)
diff --git a/app/assets/javascripts/discourse/controllers/navigation/default.js.es6 b/app/assets/javascripts/discourse/controllers/navigation/default.js.es6
index 0ad1878622..9d4d051974 100644
--- a/app/assets/javascripts/discourse/controllers/navigation/default.js.es6
+++ b/app/assets/javascripts/discourse/controllers/navigation/default.js.es6
@@ -1,8 +1,10 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
- discovery: Ember.inject.controller(),
- discoveryTopics: Ember.inject.controller("discovery/topics"),
+export default Controller.extend({
+ discovery: inject(),
+ discoveryTopics: inject("discovery/topics"),
@computed("discoveryTopics.model", "discoveryTopics.model.draft")
draft: function() {
diff --git a/app/assets/javascripts/discourse/controllers/not-activated.js.es6 b/app/assets/javascripts/discourse/controllers/not-activated.js.es6
index 71824b3e15..ba520eb6f2 100644
--- a/app/assets/javascripts/discourse/controllers/not-activated.js.es6
+++ b/app/assets/javascripts/discourse/controllers/not-activated.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { resendActivationEmail } from "discourse/lib/user-activation";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
actions: {
sendActivationEmail() {
resendActivationEmail(this.username).then(() => {
diff --git a/app/assets/javascripts/discourse/controllers/password-reset.js.es6 b/app/assets/javascripts/discourse/controllers/password-reset.js.es6
index ae3c5949a5..b7a4545aed 100644
--- a/app/assets/javascripts/discourse/controllers/password-reset.js.es6
+++ b/app/assets/javascripts/discourse/controllers/password-reset.js.es6
@@ -1,3 +1,5 @@
+import { alias, or } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import DiscourseURL from "discourse/lib/url";
import { ajax } from "discourse/lib/ajax";
@@ -6,19 +8,22 @@ import { userPath } from "discourse/lib/url";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
import { getWebauthnCredential } from "discourse/lib/webauthn";
-export default Ember.Controller.extend(PasswordValidation, {
- isDeveloper: Ember.computed.alias("model.is_developer"),
- admin: Ember.computed.alias("model.admin"),
- secondFactorRequired: Ember.computed.alias("model.second_factor_required"),
- securityKeyRequired: Ember.computed.alias("model.security_key_required"),
- backupEnabled: Ember.computed.alias("model.backup_enabled"),
- securityKeyOrSecondFactorRequired: Ember.computed.or(
+export default Controller.extend(PasswordValidation, {
+ isDeveloper: alias("model.is_developer"),
+ admin: alias("model.admin"),
+ secondFactorRequired: alias("model.second_factor_required"),
+ securityKeyRequired: alias("model.security_key_required"),
+ backupEnabled: alias("model.backup_enabled"),
+ securityKeyOrSecondFactorRequired: or(
"model.second_factor_required",
"model.security_key_required"
),
- secondFactorMethod: Ember.computed.alias("model.security_key_required")
- ? SECOND_FACTOR_METHODS.SECURITY_KEY
- : SECOND_FACTOR_METHODS.TOTP,
+ @computed("model.security_key_required")
+ secondFactorMethod(security_key_required) {
+ return security_key_required
+ ? SECOND_FACTOR_METHODS.SECURITY_KEY
+ : SECOND_FACTOR_METHODS.TOTP;
+ },
passwordRequired: true,
errorMessage: null,
successMessage: null,
diff --git a/app/assets/javascripts/discourse/controllers/preferences.js.es6 b/app/assets/javascripts/discourse/controllers/preferences.js.es6
index cda126a2e2..a422a1f33c 100644
--- a/app/assets/javascripts/discourse/controllers/preferences.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences.js.es6
@@ -1,3 +1,5 @@
-export default Ember.Controller.extend({
- router: Ember.inject.service()
+import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
+export default Controller.extend({
+ router: service()
});
diff --git a/app/assets/javascripts/discourse/controllers/preferences/about.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/about.js.es6
deleted file mode 100644
index 37e7247a8a..0000000000
--- a/app/assets/javascripts/discourse/controllers/preferences/about.js.es6
+++ /dev/null
@@ -1,11 +0,0 @@
-import computed from "ember-addons/ember-computed-decorators";
-
-export default Ember.Controller.extend({
- saving: false,
- newBio: null,
-
- @computed("saving")
- saveButtonText(saving) {
- return saving ? I18n.t("saving") : I18n.t("user.change");
- }
-});
diff --git a/app/assets/javascripts/discourse/controllers/preferences/account.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/account.js.es6
index 14fcc4b79f..e30386afdf 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/account.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/account.js.es6
@@ -1,3 +1,6 @@
+import { isEmpty } from "@ember/utils";
+import { not, or, gt } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { iconHTML } from "discourse-common/lib/icon-library";
import CanCheckEmails from "discourse/mixins/can-check-emails";
import { default as computed } from "ember-addons/ember-computed-decorators";
@@ -12,248 +15,249 @@ import { userPath } from "discourse/lib/url";
// Number of tokens shown by default.
const DEFAULT_AUTH_TOKENS_COUNT = 2;
-export default Ember.Controller.extend(
- CanCheckEmails,
- PreferencesTabController,
- {
- init() {
- this._super(...arguments);
+export default Controller.extend(CanCheckEmails, PreferencesTabController, {
+ init() {
+ this._super(...arguments);
- this.saveAttrNames = ["name", "title"];
- this.set("revoking", {});
- },
+ this.saveAttrNames = ["name", "title", "primary_group_id"];
+ this.set("revoking", {});
+ },
- canEditName: setting("enable_names"),
- canSaveUser: true,
+ canEditName: setting("enable_names"),
+ canSaveUser: true,
- newNameInput: null,
- newTitleInput: null,
+ newNameInput: null,
+ newTitleInput: null,
+ newPrimaryGroupInput: null,
- passwordProgress: null,
+ passwordProgress: null,
- showAllAuthTokens: false,
+ showAllAuthTokens: false,
- revoking: null,
+ revoking: null,
- cannotDeleteAccount: Ember.computed.not("currentUser.can_delete_account"),
- deleteDisabled: Ember.computed.or(
- "model.isSaving",
- "deleting",
- "cannotDeleteAccount"
- ),
+ cannotDeleteAccount: not("currentUser.can_delete_account"),
+ deleteDisabled: or("model.isSaving", "deleting", "cannotDeleteAccount"),
- reset() {
- this.set("passwordProgress", null);
- },
+ reset() {
+ this.set("passwordProgress", null);
+ },
- @computed()
- nameInstructions() {
- return I18n.t(
- this.siteSettings.full_name_required
- ? "user.name.instructions_required"
- : "user.name.instructions"
+ @computed()
+ nameInstructions() {
+ return I18n.t(
+ this.siteSettings.full_name_required
+ ? "user.name.instructions_required"
+ : "user.name.instructions"
+ );
+ },
+
+ canSelectTitle: gt("model.availableTitles.length", 0),
+
+ @computed("model.filteredGroups")
+ canSelectPrimaryGroup(primaryGroupOptions) {
+ return (
+ primaryGroupOptions.length > 0 &&
+ this.siteSettings.user_selected_primary_groups
+ );
+ },
+
+ @computed("model.is_anonymous")
+ canChangePassword(isAnonymous) {
+ if (isAnonymous) {
+ return false;
+ } else {
+ return (
+ !this.siteSettings.enable_sso && this.siteSettings.enable_local_logins
);
- },
+ }
+ },
- canSelectTitle: Ember.computed.gt("model.availableTitles.length", 0),
+ @computed("model.associated_accounts")
+ associatedAccountsLoaded(associatedAccounts) {
+ return typeof associatedAccounts !== "undefined";
+ },
- @computed("model.is_anonymous")
- canChangePassword(isAnonymous) {
- if (isAnonymous) {
- return false;
+ @computed("model.associated_accounts.[]")
+ authProviders(accounts) {
+ const allMethods = findAll();
+
+ const result = allMethods.map(method => {
+ return {
+ method,
+ account: accounts.find(account => account.name === method.name) // Will be undefined if no account
+ };
+ });
+
+ return result.filter(value => value.account || value.method.can_connect);
+ },
+
+ disableConnectButtons: propertyNotEqual("model.id", "currentUser.id"),
+
+ @computed(
+ "model.second_factor_enabled",
+ "canCheckEmails",
+ "model.is_anonymous"
+ )
+ canUpdateAssociatedAccounts(
+ secondFactorEnabled,
+ canCheckEmails,
+ isAnonymous
+ ) {
+ if (secondFactorEnabled || !canCheckEmails || isAnonymous) {
+ return false;
+ }
+ return findAll().length > 0;
+ },
+
+ @computed("showAllAuthTokens", "model.user_auth_tokens")
+ authTokens(showAllAuthTokens, tokens) {
+ tokens.sort((a, b) => {
+ if (a.is_active) {
+ return -1;
+ } else if (b.is_active) {
+ return 1;
} else {
- return (
- !this.siteSettings.enable_sso && this.siteSettings.enable_local_logins
+ return b.seen_at.localeCompare(a.seen_at);
+ }
+ });
+
+ return showAllAuthTokens
+ ? tokens
+ : tokens.slice(0, DEFAULT_AUTH_TOKENS_COUNT);
+ },
+
+ canShowAllAuthTokens: gt(
+ "model.user_auth_tokens.length",
+ DEFAULT_AUTH_TOKENS_COUNT
+ ),
+
+ actions: {
+ save() {
+ this.set("saved", false);
+
+ this.model.setProperties({
+ name: this.newNameInput,
+ title: this.newTitleInput,
+ primary_group_id: this.newPrimaryGroupInput
+ });
+
+ return this.model
+ .save(this.saveAttrNames)
+ .then(() => this.set("saved", true))
+ .catch(popupAjaxError);
+ },
+
+ changePassword() {
+ if (!this.passwordProgress) {
+ this.set(
+ "passwordProgress",
+ I18n.t("user.change_password.in_progress")
);
- }
- },
-
- @computed("model.associated_accounts")
- associatedAccountsLoaded(associatedAccounts) {
- return typeof associatedAccounts !== "undefined";
- },
-
- @computed("model.associated_accounts.[]")
- authProviders(accounts) {
- const allMethods = findAll();
-
- const result = allMethods.map(method => {
- return {
- method,
- account: accounts.find(account => account.name === method.name) // Will be undefined if no account
- };
- });
-
- return result.filter(value => value.account || value.method.can_connect);
- },
-
- disableConnectButtons: propertyNotEqual("model.id", "currentUser.id"),
-
- @computed(
- "model.second_factor_enabled",
- "canCheckEmails",
- "model.is_anonymous"
- )
- canUpdateAssociatedAccounts(
- secondFactorEnabled,
- canCheckEmails,
- isAnonymous
- ) {
- if (secondFactorEnabled || !canCheckEmails || isAnonymous) {
- return false;
- }
- return findAll().length > 0;
- },
-
- @computed("showAllAuthTokens", "model.user_auth_tokens")
- authTokens(showAllAuthTokens, tokens) {
- tokens.sort((a, b) => {
- if (a.is_active) {
- return -1;
- } else if (b.is_active) {
- return 1;
- } else {
- return b.seen_at.localeCompare(a.seen_at);
- }
- });
-
- return showAllAuthTokens
- ? tokens
- : tokens.slice(0, DEFAULT_AUTH_TOKENS_COUNT);
- },
-
- canShowAllAuthTokens: Ember.computed.gt(
- "model.user_auth_tokens.length",
- DEFAULT_AUTH_TOKENS_COUNT
- ),
-
- actions: {
- save() {
- this.set("saved", false);
-
- this.model.setProperties({
- name: this.newNameInput,
- title: this.newTitleInput
- });
-
return this.model
- .save(this.saveAttrNames)
- .then(() => this.set("saved", true))
- .catch(popupAjaxError);
- },
-
- changePassword() {
- if (!this.passwordProgress) {
- this.set(
- "passwordProgress",
- I18n.t("user.change_password.in_progress")
- );
- return this.model
- .changePassword()
- .then(() => {
- // password changed
- this.setProperties({
- changePasswordProgress: false,
- passwordProgress: I18n.t("user.change_password.success")
- });
- })
- .catch(() => {
- // password failed to change
- this.setProperties({
- changePasswordProgress: false,
- passwordProgress: I18n.t("user.change_password.error")
- });
- });
- }
- },
-
- delete() {
- this.set("deleting", true);
- const message = I18n.t("user.delete_account_confirm"),
- model = this.model,
- buttons = [
- {
- label: I18n.t("cancel"),
- class: "d-modal-cancel",
- link: true,
- callback: () => {
- this.set("deleting", false);
- }
- },
- {
- label:
- iconHTML("exclamation-triangle") +
- I18n.t("user.delete_account"),
- class: "btn btn-danger",
- callback() {
- model.delete().then(
- () => {
- bootbox.alert(
- I18n.t("user.deleted_yourself"),
- () => (window.location = Discourse.getURL("/"))
- );
- },
- () => {
- bootbox.alert(I18n.t("user.delete_yourself_not_allowed"));
- this.set("deleting", false);
- }
- );
- }
- }
- ];
- bootbox.dialog(message, buttons, { classes: "delete-account" });
- },
-
- revokeAccount(account) {
- this.set(`revoking.${account.name}`, true);
-
- this.model
- .revokeAssociatedAccount(account.name)
- .then(result => {
- if (result.success) {
- this.model.associated_accounts.removeObject(account);
- } else {
- bootbox.alert(result.message);
- }
- })
- .catch(popupAjaxError)
- .finally(() => this.set(`revoking.${account.name}`, false));
- },
-
- toggleShowAllAuthTokens() {
- this.toggleProperty("showAllAuthTokens");
- },
-
- revokeAuthToken(token) {
- ajax(
- userPath(
- `${this.get("model.username_lower")}/preferences/revoke-auth-token`
- ),
- {
- type: "POST",
- data: token ? { token_id: token.id } : {}
- }
- )
+ .changePassword()
.then(() => {
- if (!token) {
- const redirect = this.siteSettings.logout_redirect;
- if (Ember.isEmpty(redirect)) {
- window.location = Discourse.getURL("/");
- } else {
- window.location.href = redirect;
- }
- }
+ // password changed
+ this.setProperties({
+ changePasswordProgress: false,
+ passwordProgress: I18n.t("user.change_password.success")
+ });
})
- .catch(popupAjaxError);
- },
-
- showToken(token) {
- showModal("auth-token", { model: token });
- },
-
- connectAccount(method) {
- method.doLogin({ reconnect: true });
+ .catch(() => {
+ // password failed to change
+ this.setProperties({
+ changePasswordProgress: false,
+ passwordProgress: I18n.t("user.change_password.error")
+ });
+ });
}
+ },
+
+ delete() {
+ this.set("deleting", true);
+ const message = I18n.t("user.delete_account_confirm"),
+ model = this.model,
+ buttons = [
+ {
+ label: I18n.t("cancel"),
+ class: "d-modal-cancel",
+ link: true,
+ callback: () => {
+ this.set("deleting", false);
+ }
+ },
+ {
+ label:
+ iconHTML("exclamation-triangle") + I18n.t("user.delete_account"),
+ class: "btn btn-danger",
+ callback() {
+ model.delete().then(
+ () => {
+ bootbox.alert(
+ I18n.t("user.deleted_yourself"),
+ () => (window.location = Discourse.getURL("/"))
+ );
+ },
+ () => {
+ bootbox.alert(I18n.t("user.delete_yourself_not_allowed"));
+ this.set("deleting", false);
+ }
+ );
+ }
+ }
+ ];
+ bootbox.dialog(message, buttons, { classes: "delete-account" });
+ },
+
+ revokeAccount(account) {
+ this.set(`revoking.${account.name}`, true);
+
+ this.model
+ .revokeAssociatedAccount(account.name)
+ .then(result => {
+ if (result.success) {
+ this.model.associated_accounts.removeObject(account);
+ } else {
+ bootbox.alert(result.message);
+ }
+ })
+ .catch(popupAjaxError)
+ .finally(() => this.set(`revoking.${account.name}`, false));
+ },
+
+ toggleShowAllAuthTokens() {
+ this.toggleProperty("showAllAuthTokens");
+ },
+
+ revokeAuthToken(token) {
+ ajax(
+ userPath(
+ `${this.get("model.username_lower")}/preferences/revoke-auth-token`
+ ),
+ {
+ type: "POST",
+ data: token ? { token_id: token.id } : {}
+ }
+ )
+ .then(() => {
+ if (!token) {
+ const redirect = this.siteSettings.logout_redirect;
+ if (isEmpty(redirect)) {
+ window.location = Discourse.getURL("/");
+ } else {
+ window.location.href = redirect;
+ }
+ }
+ })
+ .catch(popupAjaxError);
+ },
+
+ showToken(token) {
+ showModal("auth-token", { model: token });
+ },
+
+ connectAccount(method) {
+ method.doLogin({ reconnect: true });
}
}
-);
+});
diff --git a/app/assets/javascripts/discourse/controllers/preferences/categories.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/categories.js.es6
index d45e3fad89..8f86974e38 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/categories.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/categories.js.es6
@@ -1,8 +1,10 @@
+import { or } from "@ember/object/computed";
+import Controller from "@ember/controller";
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(PreferencesTabController, {
+export default Controller.extend(PreferencesTabController, {
init() {
this._super(...arguments);
@@ -34,7 +36,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
return this.siteSettings.remove_muted_tags_from_latest !== "never";
},
- canSave: Ember.computed.or("canSee", "currentUser.admin"),
+ canSave: or("canSee", "currentUser.admin"),
actions: {
save() {
diff --git a/app/assets/javascripts/discourse/controllers/preferences/email.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/email.js.es6
index c7ad39668d..c25db36a43 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/email.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/email.js.es6
@@ -1,18 +1,20 @@
+import { empty, or } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { propertyEqual } from "discourse/lib/computed";
import InputValidation from "discourse/models/input-validation";
import { emailValid } from "discourse/lib/utilities";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
taken: false,
saving: false,
error: false,
success: false,
newEmail: null,
- newEmailEmpty: Ember.computed.empty("newEmail"),
+ newEmailEmpty: empty("newEmail"),
- saveDisabled: Ember.computed.or(
+ saveDisabled: or(
"saving",
"newEmailEmpty",
"taken",
diff --git a/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6
index 2db23b6f4d..a2001457e5 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6
@@ -1,3 +1,5 @@
+import { equal } from "@ember/object/computed";
+import Controller from "@ember/controller";
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
@@ -8,12 +10,12 @@ const EMAIL_LEVELS = {
NEVER: 2
};
-export default Ember.Controller.extend(PreferencesTabController, {
- emailMessagesLevelAway: Ember.computed.equal(
+export default Controller.extend(PreferencesTabController, {
+ emailMessagesLevelAway: equal(
"model.user_option.email_messages_level",
EMAIL_LEVELS.ONLY_WHEN_AWAY
),
- emailLevelAway: Ember.computed.equal(
+ emailLevelAway: equal(
"model.user_option.email_level",
EMAIL_LEVELS.ONLY_WHEN_AWAY
),
diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
index e5b7bf42bf..9ef7280fc2 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
@@ -1,3 +1,5 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
import { setDefaultHomepage } from "discourse/lib/utilities";
import {
@@ -27,7 +29,7 @@ const USER_HOMES = {
const TEXT_SIZES = ["smaller", "normal", "larger", "largest"];
const TITLE_COUNT_MODES = ["notifications", "contextual"];
-export default Ember.Controller.extend(PreferencesTabController, {
+export default Controller.extend(PreferencesTabController, {
@computed("makeThemeDefault")
saveAttrNames(makeDefault) {
let attrs = [
@@ -51,7 +53,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
return attrs;
},
- preferencesController: Ember.inject.controller("preferences"),
+ preferencesController: inject("preferences"),
@computed()
isiPad() {
diff --git a/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6
index 77690846d5..8030885efb 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/notifications.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
import { NotificationLevels } from "discourse/lib/notification-levels";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(PreferencesTabController, {
+export default Controller.extend(PreferencesTabController, {
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/controllers/preferences/profile.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/profile.js.es6
index 5d1dde4b76..b4e9a46fac 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/profile.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/profile.js.es6
@@ -1,9 +1,12 @@
+import { isEmpty } from "@ember/utils";
+import EmberObject from "@ember/object";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { cookAsync } from "discourse/lib/text";
-export default Ember.Controller.extend(PreferencesTabController, {
+export default Controller.extend(PreferencesTabController, {
init() {
this._super(...arguments);
@@ -22,7 +25,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
@computed("model.user_fields.@each.value")
userFields() {
let siteUserFields = this.site.get("user_fields");
- if (!Ember.isEmpty(siteUserFields)) {
+ if (!isEmpty(siteUserFields)) {
const userFields = this.get("model.user_fields");
// Staff can edit fields that are not `editable`
@@ -33,7 +36,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
const value = userFields
? userFields[field.get("id").toString()]
: null;
- return Ember.Object.create({ value, field });
+ return EmberObject.create({ value, field });
});
}
},
@@ -51,9 +54,9 @@ export default Ember.Controller.extend(PreferencesTabController, {
userFields = this.userFields;
// Update the user fields
- if (!Ember.isEmpty(userFields)) {
+ if (!isEmpty(userFields)) {
const modelFields = model.get("user_fields");
- if (!Ember.isEmpty(modelFields)) {
+ if (!isEmpty(modelFields)) {
userFields.forEach(function(uf) {
modelFields[uf.get("field.id").toString()] = uf.get("value");
});
diff --git a/app/assets/javascripts/discourse/controllers/preferences/second-factor.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/second-factor.js.es6
index 34eb99d0e1..233ed03390 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/second-factor.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/second-factor.js.es6
@@ -1,3 +1,5 @@
+import { alias, and } from "@ember/object/computed";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import CanCheckEmails from "discourse/mixins/can-check-emails";
import { default as DiscourseURL, userPath } from "discourse/lib/url";
@@ -6,7 +8,7 @@ import { findAll } from "discourse/models/login-method";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
import showModal from "discourse/lib/show-modal";
-export default Ember.Controller.extend(CanCheckEmails, {
+export default Controller.extend(CanCheckEmails, {
loading: false,
dirty: false,
resetPasswordLoading: false,
@@ -14,11 +16,11 @@ export default Ember.Controller.extend(CanCheckEmails, {
password: null,
errorMessage: null,
newUsername: null,
- backupEnabled: Ember.computed.alias("model.second_factor_backup_enabled"),
+ backupEnabled: alias("model.second_factor_backup_enabled"),
secondFactorMethod: SECOND_FACTOR_METHODS.TOTP,
totps: null,
- loaded: Ember.computed.and("secondFactorImage", "secondFactorKey"),
+ loaded: and("secondFactorImage", "secondFactorKey"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/controllers/preferences/tags.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/tags.js.es6
index e149711bd3..85d1241ad3 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/tags.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/tags.js.es6
@@ -1,8 +1,9 @@
+import Controller from "@ember/controller";
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(PreferencesTabController, {
+export default Controller.extend(PreferencesTabController, {
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/controllers/preferences/username.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/username.js.es6
index 367f83903c..954e8c739e 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/username.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/username.js.es6
@@ -1,3 +1,6 @@
+import { isEmpty } from "@ember/utils";
+import { empty, or } from "@ember/object/computed";
+import Controller from "@ember/controller";
import {
default as computed,
observes
@@ -7,7 +10,7 @@ import DiscourseURL from "discourse/lib/url";
import { userPath } from "discourse/lib/url";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
taken: false,
saving: false,
errorMessage: null,
@@ -15,8 +18,8 @@ export default Ember.Controller.extend({
maxLength: setting("max_username_length"),
minLength: setting("min_username_length"),
- newUsernameEmpty: Ember.computed.empty("newUsername"),
- saveDisabled: Ember.computed.or(
+ newUsernameEmpty: empty("newUsername"),
+ saveDisabled: or(
"saving",
"newUsernameEmpty",
"taken",
@@ -35,7 +38,7 @@ export default Ember.Controller.extend({
this.set("taken", false);
this.set("errorMessage", null);
- if (Ember.isEmpty(this.newUsername)) return;
+ if (isEmpty(this.newUsername)) return;
if (this.unchanged) return;
Discourse.User.checkUsername(
diff --git a/app/assets/javascripts/discourse/controllers/preferences/users.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/users.js.es6
index 9f213a3090..fc675cf052 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/users.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/users.js.es6
@@ -1,10 +1,12 @@
+import { alias, gte, or } from "@ember/object/computed";
+import Controller from "@ember/controller";
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(PreferencesTabController, {
- ignoredUsernames: Ember.computed.alias("model.ignored_usernames"),
- userIsMemberOrAbove: Ember.computed.gte("model.trust_level", 2),
- ignoredEnabled: Ember.computed.or("userIsMemberOrAbove", "model.staff"),
+export default Controller.extend(PreferencesTabController, {
+ ignoredUsernames: alias("model.ignored_usernames"),
+ userIsMemberOrAbove: gte("model.trust_level", 2),
+ ignoredEnabled: or("userIsMemberOrAbove", "model.staff"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/controllers/raw-email.js.es6 b/app/assets/javascripts/discourse/controllers/raw-email.js.es6
index e671f3eef3..fbdeb103a5 100644
--- a/app/assets/javascripts/discourse/controllers/raw-email.js.es6
+++ b/app/assets/javascripts/discourse/controllers/raw-email.js.es6
@@ -1,18 +1,20 @@
+import { equal } from "@ember/object/computed";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import Post from "discourse/models/post";
import IncomingEmail from "admin/models/incoming-email";
// This controller handles displaying of raw email
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
rawEmail: "",
textPart: "",
htmlPart: "",
tab: "raw",
- showRawEmail: Ember.computed.equal("tab", "raw"),
- showTextPart: Ember.computed.equal("tab", "text_part"),
- showHtmlPart: Ember.computed.equal("tab", "html_part"),
+ showRawEmail: equal("tab", "raw"),
+ showTextPart: equal("tab", "text_part"),
+ showHtmlPart: equal("tab", "html_part"),
onShow() {
this.send("displayRaw");
diff --git a/app/assets/javascripts/discourse/controllers/rename-tag.js.es6 b/app/assets/javascripts/discourse/controllers/rename-tag.js.es6
index 9a7a01d1ef..b08bc2d646 100644
--- a/app/assets/javascripts/discourse/controllers/rename-tag.js.es6
+++ b/app/assets/javascripts/discourse/controllers/rename-tag.js.es6
@@ -1,9 +1,10 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import computed from "ember-addons/ember-computed-decorators";
import BufferedContent from "discourse/mixins/buffered-content";
import { extractError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend(ModalFunctionality, BufferedContent, {
+export default Controller.extend(ModalFunctionality, BufferedContent, {
@computed("buffered.id", "id")
renameDisabled(inputTagName, currentTagName) {
const filterRegexp = new RegExp(this.site.tags_filter_regexp, "g");
diff --git a/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6 b/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
index d893fa5b0d..06d5f30cca 100644
--- a/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
+++ b/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
@@ -1,3 +1,6 @@
+import { sort } from "@ember/object/computed";
+import EmberObjectProxy from "@ember/object/proxy";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import ModalFunctionality from "discourse/mixins/modal-functionality";
const BufferedProxy = window.BufferedProxy; // import BufferedProxy from 'ember-buffered-proxy/proxy';
@@ -8,7 +11,7 @@ import {
} from "ember-addons/ember-computed-decorators";
import Ember from "ember";
-export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, {
+export default Controller.extend(ModalFunctionality, Ember.Evented, {
init() {
this._super(...arguments);
@@ -22,14 +25,11 @@ export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, {
@computed("site.categories")
categoriesBuffered(categories) {
- const bufProxy = Ember.ObjectProxy.extend(BufferedProxy);
+ const bufProxy = EmberObjectProxy.extend(BufferedProxy);
return categories.map(c => bufProxy.create({ content: c }));
},
- categoriesOrdered: Ember.computed.sort(
- "categoriesBuffered",
- "categoriesSorting"
- ),
+ categoriesOrdered: sort("categoriesBuffered", "categoriesSorting"),
@computed("categoriesBuffered.@each.hasBufferedChanges")
showApplyAll() {
diff --git a/app/assets/javascripts/discourse/controllers/request-group-membership-form.js.es6 b/app/assets/javascripts/discourse/controllers/request-group-membership-form.js.es6
index dd3a995160..0f316873ce 100644
--- a/app/assets/javascripts/discourse/controllers/request-group-membership-form.js.es6
+++ b/app/assets/javascripts/discourse/controllers/request-group-membership-form.js.es6
@@ -1,11 +1,14 @@
+import { isEmpty } from "@ember/utils";
+import { alias } from "@ember/object/computed";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
import DiscourseURL from "discourse/lib/url";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
- reason: Ember.computed.alias("model.membership_request_template"),
+ reason: alias("model.membership_request_template"),
@computed("model.name")
title(groupName) {
@@ -14,7 +17,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
@computed("loading", "reason")
disableSubmit(loading, reason) {
- return loading || Ember.isEmpty(reason);
+ return loading || isEmpty(reason);
},
actions: {
diff --git a/app/assets/javascripts/discourse/controllers/review-index.js.es6 b/app/assets/javascripts/discourse/controllers/review-index.js.es6
index f65fd2129b..75ab25b4f1 100644
--- a/app/assets/javascripts/discourse/controllers/review-index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/review-index.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
queryParams: [
"priority",
"type",
diff --git a/app/assets/javascripts/discourse/controllers/review-settings.js.es6 b/app/assets/javascripts/discourse/controllers/review-settings.js.es6
index d3ee32ccf7..8e670adb2a 100644
--- a/app/assets/javascripts/discourse/controllers/review-settings.js.es6
+++ b/app/assets/javascripts/discourse/controllers/review-settings.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
saving: false,
saved: false,
diff --git a/app/assets/javascripts/discourse/controllers/search-help.js.es6 b/app/assets/javascripts/discourse/controllers/search-help.js.es6
index be04358f4b..654722d2c7 100644
--- a/app/assets/javascripts/discourse/controllers/search-help.js.es6
+++ b/app/assets/javascripts/discourse/controllers/search-help.js.es6
@@ -1,7 +1,8 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
@computed
showGoogleSearch() {
return !Discourse.SiteSettings.login_required;
diff --git a/app/assets/javascripts/discourse/controllers/second-factor-add-security-key.js.es6 b/app/assets/javascripts/discourse/controllers/second-factor-add-security-key.js.es6
index f19bb5a0f7..54f41fc405 100644
--- a/app/assets/javascripts/discourse/controllers/second-factor-add-security-key.js.es6
+++ b/app/assets/javascripts/discourse/controllers/second-factor-add-security-key.js.es6
@@ -1,3 +1,4 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import {
bufferToBase64,
@@ -6,7 +7,7 @@ import {
} from "discourse/lib/webauthn";
// model for this controller is user.js.es6
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
errorMessage: null,
diff --git a/app/assets/javascripts/discourse/controllers/second-factor-add-totp.js.es6 b/app/assets/javascripts/discourse/controllers/second-factor-add-totp.js.es6
index ac105f57b2..eab4f2943f 100644
--- a/app/assets/javascripts/discourse/controllers/second-factor-add-totp.js.es6
+++ b/app/assets/javascripts/discourse/controllers/second-factor-add-totp.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
secondFactorImage: null,
secondFactorKey: null,
diff --git a/app/assets/javascripts/discourse/controllers/second-factor-backup-edit.js.es6 b/app/assets/javascripts/discourse/controllers/second-factor-backup-edit.js.es6
index e11f484fbc..2801056c71 100644
--- a/app/assets/javascripts/discourse/controllers/second-factor-backup-edit.js.es6
+++ b/app/assets/javascripts/discourse/controllers/second-factor-backup-edit.js.es6
@@ -1,15 +1,16 @@
+import { alias } from "@ember/object/computed";
+import { later } from "@ember/runloop";
+import Controller from "@ember/controller";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
loading: false,
errorMessage: null,
successMessage: null,
- backupEnabled: Ember.computed.alias("model.second_factor_backup_enabled"),
- remainingCodes: Ember.computed.alias(
- "model.second_factor_remaining_backup_codes"
- ),
+ backupEnabled: alias("model.second_factor_backup_enabled"),
+ remainingCodes: alias("model.second_factor_remaining_backup_codes"),
backupCodes: null,
secondFactorMethod: SECOND_FACTOR_METHODS.TOTP,
@@ -101,7 +102,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
},
_hideCopyMessage() {
- Ember.run.later(
+ later(
() => this.setProperties({ successMessage: null, errorMessage: null }),
2000
);
diff --git a/app/assets/javascripts/discourse/controllers/second-factor-edit-security-key.js.es6 b/app/assets/javascripts/discourse/controllers/second-factor-edit-security-key.js.es6
index 90815cfbea..8507448607 100644
--- a/app/assets/javascripts/discourse/controllers/second-factor-edit-security-key.js.es6
+++ b/app/assets/javascripts/discourse/controllers/second-factor-edit-security-key.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
actions: {
disableSecurityKey() {
this.user
diff --git a/app/assets/javascripts/discourse/controllers/second-factor-edit.js.es6 b/app/assets/javascripts/discourse/controllers/second-factor-edit.js.es6
index e39f0f2b65..c11b278158 100644
--- a/app/assets/javascripts/discourse/controllers/second-factor-edit.js.es6
+++ b/app/assets/javascripts/discourse/controllers/second-factor-edit.js.es6
@@ -1,6 +1,7 @@
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
actions: {
disableSecondFactor() {
this.user
diff --git a/app/assets/javascripts/discourse/controllers/static.js.es6 b/app/assets/javascripts/discourse/controllers/static.js.es6
index 82fd514e16..587e14da81 100644
--- a/app/assets/javascripts/discourse/controllers/static.js.es6
+++ b/app/assets/javascripts/discourse/controllers/static.js.es6
@@ -1,11 +1,14 @@
+import { equal } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import computed from "ember-addons/ember-computed-decorators";
import { userPath } from "discourse/lib/url";
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
- showLoginButton: Ember.computed.equal("model.path", "login"),
+ showLoginButton: equal("model.path", "login"),
@computed("model.path")
bodyClass: path => `static-${path}`,
diff --git a/app/assets/javascripts/discourse/controllers/tag-groups-edit.js.es6 b/app/assets/javascripts/discourse/controllers/tag-groups-edit.js.es6
new file mode 100644
index 0000000000..067a2f615b
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/tag-groups-edit.js.es6
@@ -0,0 +1,15 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
+
+export default Controller.extend({
+ tagGroups: inject(),
+
+ actions: {
+ onDestroy() {
+ const tagGroups = this.tagGroups.model;
+ tagGroups.removeObject(this.model);
+
+ this.transitionToRoute("tagGroups.index");
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/controllers/tag-groups-new.js.es6 b/app/assets/javascripts/discourse/controllers/tag-groups-new.js.es6
new file mode 100644
index 0000000000..e4a3a0187e
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/tag-groups-new.js.es6
@@ -0,0 +1,14 @@
+import Controller from "@ember/controller";
+
+export default Controller.extend({
+ tagGroups: Ember.inject.controller(),
+
+ actions: {
+ onSave() {
+ const tagGroups = this.tagGroups.model;
+ tagGroups.pushObject(this.model);
+
+ this.transitionToRoute("tagGroups.edit", this.model);
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/controllers/tag-groups-show.js.es6 b/app/assets/javascripts/discourse/controllers/tag-groups-show.js.es6
deleted file mode 100644
index 7b80def0b7..0000000000
--- a/app/assets/javascripts/discourse/controllers/tag-groups-show.js.es6
+++ /dev/null
@@ -1,26 +0,0 @@
-export default Ember.Controller.extend({
- tagGroups: Ember.inject.controller(),
-
- actions: {
- save() {
- this.model.save();
- },
-
- destroy() {
- return bootbox.confirm(
- I18n.t("tagging.groups.confirm_delete"),
- I18n.t("no_value"),
- I18n.t("yes_value"),
- destroy => {
- if (destroy) {
- const c = this.get("tagGroups.model");
- return this.model.destroy().then(() => {
- c.removeObject(this.model);
- this.transitionToRoute("tagGroups");
- });
- }
- }
- );
- }
- }
-});
diff --git a/app/assets/javascripts/discourse/controllers/tag-groups.js.es6 b/app/assets/javascripts/discourse/controllers/tag-groups.js.es6
index e4515d90b9..725f8846f1 100644
--- a/app/assets/javascripts/discourse/controllers/tag-groups.js.es6
+++ b/app/assets/javascripts/discourse/controllers/tag-groups.js.es6
@@ -1,24 +1,9 @@
-import TagGroup from "discourse/models/tag-group";
+import Controller from "@ember/controller";
-export default Ember.Controller.extend({
+export default Controller.extend({
actions: {
- selectTagGroup(tagGroup) {
- if (this.selectedItem) {
- this.selectedItem.set("selected", false);
- }
- this.set("selectedItem", tagGroup);
- tagGroup.set("selected", true);
- tagGroup.set("savingStatus", null);
- this.transitionToRoute("tagGroups.show", tagGroup);
- },
-
newTagGroup() {
- const newTagGroup = TagGroup.create({
- id: "new",
- name: I18n.t("tagging.groups.new_name")
- });
- this.model.pushObject(newTagGroup);
- this.send("selectTagGroup", newTagGroup);
+ this.transitionToRoute("tagGroups.new");
}
}
});
diff --git a/app/assets/javascripts/discourse/controllers/tags-index.js.es6 b/app/assets/javascripts/discourse/controllers/tags-index.js.es6
index fa20f97f2f..c2ec12fda6 100644
--- a/app/assets/javascripts/discourse/controllers/tags-index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/tags-index.js.es6
@@ -1,15 +1,17 @@
+import { alias, notEmpty } from "@ember/object/computed";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import showModal from "discourse/lib/show-modal";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Ember.Controller.extend({
+export default Controller.extend({
sortedByCount: true,
sortedByName: false,
- canAdminTags: Ember.computed.alias("currentUser.staff"),
- groupedByCategory: Ember.computed.notEmpty("model.extras.categories"),
- groupedByTagGroup: Ember.computed.notEmpty("model.extras.tag_groups"),
+ canAdminTags: alias("currentUser.staff"),
+ groupedByCategory: notEmpty("model.extras.categories"),
+ groupedByTagGroup: notEmpty("model.extras.tag_groups"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/controllers/tags-show.js.es6 b/app/assets/javascripts/discourse/controllers/tags-show.js.es6
index 0c1c77e610..9d787fe8a4 100644
--- a/app/assets/javascripts/discourse/controllers/tags-show.js.es6
+++ b/app/assets/javascripts/discourse/controllers/tags-show.js.es6
@@ -1,3 +1,6 @@
+import { alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import {
default as computed,
observes
@@ -48,13 +51,13 @@ if (customNavItemHref) {
});
}
-export default Ember.Controller.extend(BulkTopicSelection, {
- application: Ember.inject.controller(),
+export default Controller.extend(BulkTopicSelection, {
+ application: inject(),
tag: null,
additionalTags: null,
list: null,
- canAdminTag: Ember.computed.alias("currentUser.staff"),
+ canAdminTag: alias("currentUser.staff"),
filterMode: null,
navMode: "latest",
loading: false,
@@ -67,7 +70,7 @@ export default Ember.Controller.extend(BulkTopicSelection, {
max_posts: null,
q: null,
- categories: Ember.computed.alias("site.categoriesList"),
+ categories: alias("site.categoriesList"),
@computed("list", "list.draft")
createTopicLabel(list, listDraft) {
diff --git a/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6 b/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6
index 5d9c287cf2..d2a809fc6e 100644
--- a/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6
+++ b/app/assets/javascripts/discourse/controllers/topic-bulk-actions.js.es6
@@ -1,3 +1,5 @@
+import { empty, alias } from "@ember/object/computed";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
const _buttons = [];
@@ -67,11 +69,11 @@ addBulkButton("deleteTopics", "delete", {
});
// Modal for performing bulk actions on topics
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
tags: null,
- emptyTags: Ember.computed.empty("tags"),
- categoryId: Ember.computed.alias("model.category.id"),
+ emptyTags: empty("tags"),
+ categoryId: alias("model.category.id"),
onShow() {
const topics = this.get("model.topics");
diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6
index f459e4bcec..af63f140be 100644
--- a/app/assets/javascripts/discourse/controllers/topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/topic.js.es6
@@ -1,3 +1,10 @@
+import { isEmpty } from "@ember/utils";
+import { or, and, not, alias } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { next } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import Composer from "discourse/models/composer";
import DiscourseURL from "discourse/lib/url";
@@ -18,6 +25,7 @@ import { spinnerHTML } from "discourse/helpers/loading-spinner";
import { userPath } from "discourse/lib/url";
import showModal from "discourse/lib/show-modal";
import TopicTimer from "discourse/models/topic-timer";
+import { Promise } from "rsvp";
let customPostMessageCallbacks = {};
@@ -33,14 +41,14 @@ export function registerCustomPostMessageCallback(type, callback) {
customPostMessageCallbacks[type] = callback;
}
-export default Ember.Controller.extend(bufferedProperty("model"), {
- composer: Ember.inject.controller(),
- application: Ember.inject.controller(),
+export default Controller.extend(bufferedProperty("model"), {
+ composer: inject(),
+ application: inject(),
multiSelect: false,
selectedPostIds: null,
editingTopic: false,
queryParams: ["filter", "username_filters"],
- loadedAllPosts: Ember.computed.or(
+ loadedAllPosts: or(
"model.postStream.loadedAllPosts",
"model.postStream.loadingLastPost"
),
@@ -54,7 +62,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
filter: null,
quoteState: null,
- canRemoveTopicFeaturedLink: Ember.computed.and(
+ canRemoveTopicFeaturedLink: and(
"canEditTopicFeaturedLink",
"buffered.featured_link"
),
@@ -66,7 +74,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
@observes("model.title", "category")
_titleChanged() {
const title = this.get("model.title");
- if (!Ember.isEmpty(title)) {
+ if (!isEmpty(title)) {
// force update lazily loaded titles
this.send("refreshTitle");
}
@@ -130,12 +138,12 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
return;
}
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
this.send("showHistory", post, revision);
});
},
- showCategoryChooser: Ember.computed.not("model.isPrivateMessage"),
+ showCategoryChooser: not("model.isPrivateMessage"),
gotoInbox(name) {
let url = userPath(this.get("currentUser.username_lower") + "/messages");
@@ -261,7 +269,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
selectText(postId, buffer) {
const loadedPost = this.get("model.postStream").findLoadedPost(postId);
const promise = loadedPost
- ? Ember.RSVP.resolve(loadedPost)
+ ? Promise.resolve(loadedPost)
: this.get("model.postStream").loadPost(postId);
return promise.then(post => {
@@ -819,7 +827,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
},
addNotice(post) {
- return new Ember.RSVP.Promise(function(resolve, reject) {
+ return new Promise(function(resolve, reject) {
const controller = showModal("add-post-notice");
controller.setProperties({ post, resolve, reject });
});
@@ -965,13 +973,13 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
options = {
action: Composer.PRIVATE_MESSAGE,
archetypeId: "private_message",
- draftKey: Composer.REPLY_AS_NEW_PRIVATE_MESSAGE_KEY,
+ draftKey: post.topic.draft_key,
usernames: usernames
};
} else {
options = {
action: Composer.CREATE_TOPIC,
- draftKey: Composer.REPLY_AS_NEW_TOPIC_KEY,
+ draftKey: post.topic.draft_key,
categoryId: this.get("model.category.id")
};
}
@@ -979,7 +987,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
composerController
.open(options)
.then(() => {
- return Ember.isEmpty(quotedText) ? "" : quotedText;
+ return isEmpty(quotedText) ? "" : quotedText;
})
.then(q => {
const postUrl = `${location.protocol}//${location.host}${post.get(
@@ -1056,7 +1064,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
statusType,
null
)
- .then(() => this.set(`model.${topicTimer}`, Ember.Object.create({})))
+ .then(() => this.set(`model.${topicTimer}`, EmberObject.create({})))
.catch(error => popupAjaxError(error));
}
},
@@ -1142,12 +1150,12 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
}
},
- hasError: Ember.computed.or("model.errorHtml", "model.errorMessage"),
- noErrorYet: Ember.computed.not("hasError"),
+ hasError: or("model.errorHtml", "model.errorMessage"),
+ noErrorYet: not("hasError"),
- categories: Ember.computed.alias("site.categoriesList"),
+ categories: alias("site.categoriesList"),
- selectedPostsCount: Ember.computed.alias("selectedPostIds.length"),
+ selectedPostsCount: alias("selectedPostIds.length"),
@computed(
"selectedPostIds",
@@ -1196,7 +1204,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
return isMegaTopic ? false : !selectedAllPosts;
},
- canDeselectAll: Ember.computed.alias("selectedAllPosts"),
+ canDeselectAll: alias("selectedAllPosts"),
@computed(
"currentUser.staff",
@@ -1423,7 +1431,7 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
// automatically unpin topics when the user reaches the bottom
const max = _.max(postNumbers);
if (topic.get("pinned") && max >= topic.get("highest_post_number")) {
- Ember.run.next(() => topic.clearPin());
+ next(() => topic.clearPin());
}
}
}
diff --git a/app/assets/javascripts/discourse/controllers/upload-selector.js.es6 b/app/assets/javascripts/discourse/controllers/upload-selector.js.es6
index 73397bb07a..87c73494a0 100644
--- a/app/assets/javascripts/discourse/controllers/upload-selector.js.es6
+++ b/app/assets/javascripts/discourse/controllers/upload-selector.js.es6
@@ -1,3 +1,5 @@
+import { equal } from "@ember/object/computed";
+import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import {
default as computed,
@@ -17,12 +19,12 @@ function uploadTranslate(key) {
return `upload_selector.${key}`;
}
-export default Ember.Controller.extend(ModalFunctionality, {
+export default Controller.extend(ModalFunctionality, {
showMore: false,
imageUrl: null,
imageLink: null,
- local: Ember.computed.equal("selection", "local"),
- remote: Ember.computed.equal("selection", "remote"),
+ local: equal("selection", "local"),
+ remote: equal("selection", "remote"),
selection: "local",
@computed()
diff --git a/app/assets/javascripts/discourse/controllers/user-activity.js.es6 b/app/assets/javascripts/discourse/controllers/user-activity.js.es6
index d8e6f29dca..596125d221 100644
--- a/app/assets/javascripts/discourse/controllers/user-activity.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-activity.js.es6
@@ -1,12 +1,16 @@
+import { alias } from "@ember/object/computed";
+import { inject as service } from "@ember/service";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { exportUserArchive } from "discourse/lib/export-csv";
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
- router: Ember.inject.service(),
- user: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
+ router: service(),
+ user: inject(),
userActionType: null,
- canDownloadPosts: Ember.computed.alias("user.viewingSelf"),
+ canDownloadPosts: alias("user.viewingSelf"),
_showFooter: function() {
var showFooter;
diff --git a/app/assets/javascripts/discourse/controllers/user-badges.js.es6 b/app/assets/javascripts/discourse/controllers/user-badges.js.es6
index 9046c373bd..01df9566af 100644
--- a/app/assets/javascripts/discourse/controllers/user-badges.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-badges.js.es6
@@ -1,7 +1,10 @@
-export default Ember.Controller.extend({
- user: Ember.inject.controller(),
- username: Ember.computed.alias("user.model.username_lower"),
- sortedBadges: Ember.computed.sort("model", "badgeSortOrder"),
+import { alias, sort } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
+export default Controller.extend({
+ user: inject(),
+ username: alias("user.model.username_lower"),
+ sortedBadges: sort("model", "badgeSortOrder"),
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/controllers/user-card.js.es6 b/app/assets/javascripts/discourse/controllers/user-card.js.es6
index 0f26ea5e59..d0fa3abf1c 100644
--- a/app/assets/javascripts/discourse/controllers/user-card.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-card.js.es6
@@ -1,12 +1,15 @@
+import { inject as service } from "@ember/service";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import {
default as DiscourseURL,
userPath,
groupPath
} from "discourse/lib/url";
-export default Ember.Controller.extend({
- topic: Ember.inject.controller(),
- router: Ember.inject.service(),
+export default Controller.extend({
+ topic: inject(),
+ router: service(),
actions: {
togglePosts(user) {
diff --git a/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6 b/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6
index 23bbd45295..8a8c102b0e 100644
--- a/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6
@@ -1,3 +1,5 @@
+import { equal, reads, gte } from "@ember/object/computed";
+import Controller from "@ember/controller";
import Invite from "discourse/models/invite";
import debounce from "discourse/lib/debounce";
import { popupAjaxError } from "discourse/lib/ajax-error";
@@ -6,7 +8,7 @@ import {
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
+export default Controller.extend({
user: null,
model: null,
filter: null,
@@ -31,7 +33,7 @@ export default Ember.Controller.extend({
);
}, 250),
- inviteRedeemed: Ember.computed.equal("filter", "redeemed"),
+ inviteRedeemed: equal("filter", "redeemed"),
@computed("filter")
showBulkActionButtons(filter) {
@@ -42,11 +44,11 @@ export default Ember.Controller.extend({
);
},
- canInviteToForum: Ember.computed.reads("currentUser.can_invite_to_forum"),
+ canInviteToForum: reads("currentUser.can_invite_to_forum"),
- canBulkInvite: Ember.computed.reads("currentUser.admin"),
+ canBulkInvite: reads("currentUser.admin"),
- showSearch: Ember.computed.gte("totalInvites", 10),
+ showSearch: gte("totalInvites", 10),
@computed("invitesCount.total", "invitesCount.pending")
pendingLabel(invitesCountTotal, invitesCountPending) {
diff --git a/app/assets/javascripts/discourse/controllers/user-notifications.js.es6 b/app/assets/javascripts/discourse/controllers/user-notifications.js.es6
index bb94ee6f50..ea5507cc5c 100644
--- a/app/assets/javascripts/discourse/controllers/user-notifications.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-notifications.js.es6
@@ -1,11 +1,13 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
@observes("model.canLoadMore")
_showFooter() {
diff --git a/app/assets/javascripts/discourse/controllers/user-posts.js.es6 b/app/assets/javascripts/discourse/controllers/user-posts.js.es6
index 25c730d97a..fe001ad1c1 100644
--- a/app/assets/javascripts/discourse/controllers/user-posts.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-posts.js.es6
@@ -1,5 +1,7 @@
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
+export default Controller.extend({
+ application: inject(),
_showFooter: function() {
this.set("application.showFooter", !this.get("model.canLoadMore"));
diff --git a/app/assets/javascripts/discourse/controllers/user-private-messages-tags.js.es6 b/app/assets/javascripts/discourse/controllers/user-private-messages-tags.js.es6
index 1be6e948c4..d1c311f893 100644
--- a/app/assets/javascripts/discourse/controllers/user-private-messages-tags.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-private-messages-tags.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Controller.extend({
+import Controller from "@ember/controller";
+export default Controller.extend({
sortProperties: ["count:desc", "id"],
tagsForUser: null,
sortedByCount: true,
diff --git a/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6 b/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6
index c5e1bd9452..c6252978c9 100644
--- a/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6
@@ -1,25 +1,26 @@
+import { alias, equal, and } from "@ember/object/computed";
+import { inject as service } from "@ember/service";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import Topic from "discourse/models/topic";
-export default Ember.Controller.extend({
- router: Ember.inject.service(),
- userTopicsList: Ember.inject.controller("user-topics-list"),
- user: Ember.inject.controller(),
+export default Controller.extend({
+ router: service(),
+ userTopicsList: inject("user-topics-list"),
+ user: inject(),
pmView: false,
- viewingSelf: Ember.computed.alias("user.viewingSelf"),
- isGroup: Ember.computed.equal("pmView", "groups"),
- currentPath: Ember.computed.alias("router._router.currentPath"),
- selected: Ember.computed.alias("userTopicsList.selected"),
- bulkSelectEnabled: Ember.computed.alias("userTopicsList.bulkSelectEnabled"),
+ viewingSelf: alias("user.viewingSelf"),
+ isGroup: equal("pmView", "groups"),
+ currentPath: alias("router._router.currentPath"),
+ selected: alias("userTopicsList.selected"),
+ bulkSelectEnabled: alias("userTopicsList.bulkSelectEnabled"),
showToggleBulkSelect: true,
- pmTaggingEnabled: Ember.computed.alias("site.can_tag_pms"),
+ pmTaggingEnabled: alias("site.can_tag_pms"),
tagId: null,
- showNewPM: Ember.computed.and(
- "user.viewingSelf",
- "currentUser.can_send_private_messages"
- ),
+ showNewPM: and("user.viewingSelf", "currentUser.can_send_private_messages"),
@computed("selected.[]", "bulkSelectEnabled")
hasSelection(selected, bulkSelectEnabled) {
diff --git a/app/assets/javascripts/discourse/controllers/user-summary.js.es6 b/app/assets/javascripts/discourse/controllers/user-summary.js.es6
index 2e88396cb7..7383cfa336 100644
--- a/app/assets/javascripts/discourse/controllers/user-summary.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-summary.js.es6
@@ -1,12 +1,15 @@
+import { alias } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
import { durationTiny } from "discourse/lib/formatter";
// should be kept in sync with 'UserSummary::MAX_BADGES'
const MAX_BADGES = 6;
-export default Ember.Controller.extend({
- userController: Ember.inject.controller("user"),
- user: Ember.computed.alias("userController.model"),
+export default Controller.extend({
+ userController: inject("user"),
+ user: alias("userController.model"),
@computed("model.badges.length")
moreBadges(badgesLength) {
diff --git a/app/assets/javascripts/discourse/controllers/user-topics-list.js.es6 b/app/assets/javascripts/discourse/controllers/user-topics-list.js.es6
index a4d822a565..5539500165 100644
--- a/app/assets/javascripts/discourse/controllers/user-topics-list.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-topics-list.js.es6
@@ -1,8 +1,10 @@
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import computed from "ember-addons/ember-computed-decorators";
// Lists of topics on a user's page.
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
hideCategory: false,
showPosters: false,
@@ -16,6 +18,10 @@ export default Ember.Controller.extend({
this.newIncoming = [];
},
+ saveScrollPosition: function() {
+ this.session.set("topicListScrollPosition", $(window).scrollTop());
+ },
+
_showFooter: function() {
this.set("application.showFooter", !this.get("model.canLoadMore"));
}.observes("model.canLoadMore"),
diff --git a/app/assets/javascripts/discourse/controllers/user.js.es6 b/app/assets/javascripts/discourse/controllers/user.js.es6
index e59b0edfdc..e24bf67a68 100644
--- a/app/assets/javascripts/discourse/controllers/user.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user.js.es6
@@ -1,14 +1,21 @@
+import { isEmpty } from "@ember/utils";
+import { alias, or, gt, not, and } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { inject as service } from "@ember/service";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import CanCheckEmails from "discourse/mixins/can-check-emails";
import computed from "ember-addons/ember-computed-decorators";
import User from "discourse/models/user";
import optionalService from "discourse/lib/optional-service";
import { prioritizeNameInUx } from "discourse/lib/settings";
+import { set } from "@ember/object";
-export default Ember.Controller.extend(CanCheckEmails, {
+export default Controller.extend(CanCheckEmails, {
indexStream: false,
- router: Ember.inject.service(),
- userNotifications: Ember.inject.controller("user-notifications"),
- currentPath: Ember.computed.alias("router._router.currentPath"),
+ router: service(),
+ userNotifications: inject("user-notifications"),
+ currentPath: alias("router._router.currentPath"),
adminTools: optionalService(),
@computed("model.username")
@@ -24,7 +31,7 @@ export default Ember.Controller.extend(CanCheckEmails, {
@computed("model.profileBackgroundUrl")
hasProfileBackgroundUrl(background) {
- return !Ember.isEmpty(background.toString());
+ return !isEmpty(background.toString());
},
@computed("model.profile_hidden", "indexStream", "viewingSelf", "forceExpand")
@@ -34,17 +41,14 @@ export default Ember.Controller.extend(CanCheckEmails, {
}
return (!indexStream || viewingSelf) && !forceExpand;
},
- canMuteOrIgnoreUser: Ember.computed.or(
- "model.can_ignore_user",
- "model.can_mute_user"
- ),
- hasGivenFlags: Ember.computed.gt("model.number_of_flags_given", 0),
- hasFlaggedPosts: Ember.computed.gt("model.number_of_flagged_posts", 0),
- hasDeletedPosts: Ember.computed.gt("model.number_of_deleted_posts", 0),
- hasBeenSuspended: Ember.computed.gt("model.number_of_suspensions", 0),
- hasReceivedWarnings: Ember.computed.gt("model.warnings_received_count", 0),
+ canMuteOrIgnoreUser: or("model.can_ignore_user", "model.can_mute_user"),
+ hasGivenFlags: gt("model.number_of_flags_given", 0),
+ hasFlaggedPosts: gt("model.number_of_flagged_posts", 0),
+ hasDeletedPosts: gt("model.number_of_deleted_posts", 0),
+ hasBeenSuspended: gt("model.number_of_suspensions", 0),
+ hasReceivedWarnings: gt("model.warnings_received_count", 0),
- showStaffCounters: Ember.computed.or(
+ showStaffCounters: or(
"hasGivenFlags",
"hasFlaggedPosts",
"hasDeletedPosts",
@@ -57,7 +61,7 @@ export default Ember.Controller.extend(CanCheckEmails, {
return !suspended || isStaff;
},
- linkWebsite: Ember.computed.not("model.isBasic"),
+ linkWebsite: not("model.isBasic"),
@computed("model.trust_level")
removeNoFollow(trustLevel) {
@@ -101,27 +105,22 @@ export default Ember.Controller.extend(CanCheckEmails, {
return User.currentProp("can_invite_to_forum");
},
- canDeleteUser: Ember.computed.and(
- "model.can_be_deleted",
- "model.can_delete_all_posts"
- ),
+ canDeleteUser: and("model.can_be_deleted", "model.can_delete_all_posts"),
@computed("model.user_fields.@each.value")
publicUserFields() {
const siteUserFields = this.site.get("user_fields");
- if (!Ember.isEmpty(siteUserFields)) {
+ if (!isEmpty(siteUserFields)) {
const userFields = this.get("model.user_fields");
return siteUserFields
.filterBy("show_on_profile", true)
.sortBy("position")
.map(field => {
- Ember.set(field, "dasherized_name", field.get("name").dasherize());
+ set(field, "dasherized_name", field.get("name").dasherize());
const value = userFields
? userFields[field.get("id").toString()]
: null;
- return Ember.isEmpty(value)
- ? null
- : Ember.Object.create({ value, field });
+ return isEmpty(value) ? null : EmberObject.create({ value, field });
})
.compact();
}
diff --git a/app/assets/javascripts/discourse/controllers/users.js.es6 b/app/assets/javascripts/discourse/controllers/users.js.es6
index 2fa9a8de59..36e3236ffd 100644
--- a/app/assets/javascripts/discourse/controllers/users.js.es6
+++ b/app/assets/javascripts/discourse/controllers/users.js.es6
@@ -1,7 +1,10 @@
+import { equal } from "@ember/object/computed";
+import { inject } from "@ember/controller";
+import Controller from "@ember/controller";
import debounce from "discourse/lib/debounce";
-export default Ember.Controller.extend({
- application: Ember.inject.controller(),
+export default Controller.extend({
+ application: inject(),
queryParams: ["period", "order", "asc", "name", "group", "exclude_usernames"],
period: "weekly",
order: "likes_received",
@@ -10,7 +13,7 @@ export default Ember.Controller.extend({
group: null,
exclude_usernames: null,
- showTimeRead: Ember.computed.equal("period", "all"),
+ showTimeRead: equal("period", "all"),
_setName: debounce(function() {
this.set("name", this.nameInput);
diff --git a/app/assets/javascripts/discourse/helpers/bound-avatar-template.js.es6 b/app/assets/javascripts/discourse/helpers/bound-avatar-template.js.es6
index 30cb9aa3bd..b08e483b2e 100644
--- a/app/assets/javascripts/discourse/helpers/bound-avatar-template.js.es6
+++ b/app/assets/javascripts/discourse/helpers/bound-avatar-template.js.es6
@@ -1,8 +1,9 @@
+import { isEmpty } from "@ember/utils";
import { htmlHelper } from "discourse-common/lib/helpers";
import { avatarImg } from "discourse/lib/utilities";
export default htmlHelper((avatarTemplate, size) => {
- if (Ember.isEmpty(avatarTemplate)) {
+ if (isEmpty(avatarTemplate)) {
return "
";
} else {
return avatarImg({ size, avatarTemplate });
diff --git a/app/assets/javascripts/discourse/helpers/bound-avatar.js.es6 b/app/assets/javascripts/discourse/helpers/bound-avatar.js.es6
index 077e823220..6504dc1c08 100644
--- a/app/assets/javascripts/discourse/helpers/bound-avatar.js.es6
+++ b/app/assets/javascripts/discourse/helpers/bound-avatar.js.es6
@@ -1,12 +1,14 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
import { htmlHelper } from "discourse-common/lib/helpers";
import { avatarImg } from "discourse/lib/utilities";
import { addExtraUserClasses } from "discourse/helpers/user-avatar";
export default htmlHelper((user, size) => {
- if (Ember.isEmpty(user)) {
+ if (isEmpty(user)) {
return "
";
}
- const avatarTemplate = Ember.get(user, "avatar_template");
+ const avatarTemplate = get(user, "avatar_template");
return avatarImg(addExtraUserClasses(user, { size, avatarTemplate }));
});
diff --git a/app/assets/javascripts/discourse/helpers/category-link.js.es6 b/app/assets/javascripts/discourse/helpers/category-link.js.es6
index 7f02dae280..c76382c8df 100644
--- a/app/assets/javascripts/discourse/helpers/category-link.js.es6
+++ b/app/assets/javascripts/discourse/helpers/category-link.js.es6
@@ -1,10 +1,9 @@
+import { get } from "@ember/object";
import { registerUnbound } from "discourse-common/lib/helpers";
import { isRTL } from "discourse/lib/text-direction";
import { iconHTML } from "discourse-common/lib/icon-library";
-var get = Ember.get,
- escapeExpression = Handlebars.Utils.escapeExpression;
-
+let escapeExpression = Handlebars.Utils.escapeExpression;
let _renderer = defaultCategoryLinkRenderer;
export function replaceCategoryLinkRenderer(fn) {
@@ -32,7 +31,7 @@ export function categoryBadgeHTML(category, opts) {
if (
!category ||
(!opts.allowUncategorized &&
- Ember.get(category, "id") ===
+ get(category, "id") ===
Discourse.Site.currentProp("uncategorized_category_id") &&
Discourse.SiteSettings.suppress_uncategorized_badge)
)
diff --git a/app/assets/javascripts/discourse/helpers/dash-if-empty.js.es6 b/app/assets/javascripts/discourse/helpers/dash-if-empty.js.es6
index 18370df0d2..96d594e650 100644
--- a/app/assets/javascripts/discourse/helpers/dash-if-empty.js.es6
+++ b/app/assets/javascripts/discourse/helpers/dash-if-empty.js.es6
@@ -1,3 +1,4 @@
+import { isEmpty } from "@ember/utils";
import { htmlHelper } from "discourse-common/lib/helpers";
-export default htmlHelper(str => (Ember.isEmpty(str) ? "—" : str));
+export default htmlHelper(str => (isEmpty(str) ? "—" : str));
diff --git a/app/assets/javascripts/discourse/helpers/dasherize.js.es6 b/app/assets/javascripts/discourse/helpers/dasherize.js.es6
index b824006169..ce9aaed3af 100644
--- a/app/assets/javascripts/discourse/helpers/dasherize.js.es6
+++ b/app/assets/javascripts/discourse/helpers/dasherize.js.es6
@@ -1,5 +1,7 @@
+import Helper from "@ember/component/helper";
+
function dasherize([value]) {
return (value || "").replace(".", "-").dasherize();
}
-export default Ember.Helper.helper(dasherize);
+export default Helper.helper(dasherize);
diff --git a/app/assets/javascripts/discourse/helpers/editable-value.js.es6 b/app/assets/javascripts/discourse/helpers/editable-value.js.es6
index 799815590a..ae67cedf5e 100644
--- a/app/assets/javascripts/discourse/helpers/editable-value.js.es6
+++ b/app/assets/javascripts/discourse/helpers/editable-value.js.es6
@@ -1,10 +1,13 @@
+import { get } from "@ember/object";
+import Helper from "@ember/component/helper";
+
export function formatCurrency([reviewable, fieldId]) {
// The field `category_id` corresponds to `category`
if (fieldId === "category_id") {
fieldId = "category.id";
}
- let value = Ember.get(reviewable, fieldId);
+ let value = get(reviewable, fieldId);
// If it's an array, say tags, make a copy so we aren't mutating the original
if (Array.isArray(value)) {
@@ -14,4 +17,4 @@ export function formatCurrency([reviewable, fieldId]) {
return value;
}
-export default Ember.Helper.helper(formatCurrency);
+export default Helper.helper(formatCurrency);
diff --git a/app/assets/javascripts/discourse/helpers/icon-or-image.js.es6 b/app/assets/javascripts/discourse/helpers/icon-or-image.js.es6
index 0751b6f0e2..f038d40eb4 100644
--- a/app/assets/javascripts/discourse/helpers/icon-or-image.js.es6
+++ b/app/assets/javascripts/discourse/helpers/icon-or-image.js.es6
@@ -1,12 +1,13 @@
+import { isEmpty } from "@ember/utils";
import { htmlHelper } from "discourse-common/lib/helpers";
import { iconHTML, convertIconClass } from "discourse-common/lib/icon-library";
export default htmlHelper(function({ icon, image }) {
- if (!Ember.isEmpty(image)) {
+ if (!isEmpty(image)) {
return ` `;
}
- if (Ember.isEmpty(icon)) {
+ if (isEmpty(icon)) {
return "";
}
diff --git a/app/assets/javascripts/discourse/helpers/user-avatar.js.es6 b/app/assets/javascripts/discourse/helpers/user-avatar.js.es6
index ff09e4e2fc..b46a49d6ff 100644
--- a/app/assets/javascripts/discourse/helpers/user-avatar.js.es6
+++ b/app/assets/javascripts/discourse/helpers/user-avatar.js.es6
@@ -1,3 +1,4 @@
+import { get } from "@ember/object";
import { registerUnbound } from "discourse-common/lib/helpers";
import { avatarImg, formatUsername } from "discourse/lib/utilities";
@@ -30,9 +31,9 @@ function renderAvatar(user, options) {
options = options || {};
if (user) {
- const name = Ember.get(user, options.namePath || "name");
- const username = Ember.get(user, options.usernamePath || "username");
- const avatarTemplate = Ember.get(
+ const name = get(user, options.namePath || "name");
+ const username = get(user, options.usernamePath || "username");
+ const avatarTemplate = get(
user,
options.avatarTemplatePath || "avatar_template"
);
@@ -46,11 +47,11 @@ function renderAvatar(user, options) {
let title = options.title;
if (!title && !options.ignoreTitle) {
// first try to get a title
- title = Ember.get(user, "title");
+ title = get(user, "title");
// if there was no title provided
if (!title) {
// try to retrieve a description
- const description = Ember.get(user, "description");
+ const description = get(user, "description");
// if a description has been provided
if (description && description.length > 0) {
// preprend the username before the description
@@ -61,7 +62,7 @@ function renderAvatar(user, options) {
return avatarImg({
size: options.imageSize,
- extraClasses: Ember.get(user, "extras") || options.extraClasses,
+ extraClasses: get(user, "extras") || options.extraClasses,
title: title || displayName,
avatarTemplate: avatarTemplate
});
diff --git a/app/assets/javascripts/discourse/initializers/asset-version.js.es6 b/app/assets/javascripts/discourse/initializers/asset-version.js.es6
index 21faedd650..f685d1b091 100644
--- a/app/assets/javascripts/discourse/initializers/asset-version.js.es6
+++ b/app/assets/javascripts/discourse/initializers/asset-version.js.es6
@@ -1,3 +1,4 @@
+import { later } from "@ember/runloop";
// Subscribe to "asset-version" change events via the Message Bus
export default {
name: "asset-version",
@@ -16,7 +17,7 @@ export default {
if (!timeoutIsSet && Discourse.get("requiresRefresh")) {
// Since we can do this transparently for people browsing the forum
// hold back the message 24 hours.
- Ember.run.later(() => {
+ later(() => {
bootbox.confirm(I18n.t("assets_changed_confirm"), function(result) {
if (result) {
document.location.reload();
diff --git a/app/assets/javascripts/discourse/initializers/auth-complete.js.es6 b/app/assets/javascripts/discourse/initializers/auth-complete.js.es6
index 83e0183ff3..31101d9010 100644
--- a/app/assets/javascripts/discourse/initializers/auth-complete.js.es6
+++ b/app/assets/javascripts/discourse/initializers/auth-complete.js.es6
@@ -1,3 +1,4 @@
+import { next } from "@ember/runloop";
export default {
name: "auth-complete",
after: "inject-objects",
@@ -13,7 +14,7 @@ export default {
if (lastAuthResult) {
const router = container.lookup("router:main");
router.one("didTransition", () => {
- Ember.run.next(() =>
+ next(() =>
Discourse.authenticationComplete(JSON.parse(lastAuthResult))
);
});
diff --git a/app/assets/javascripts/discourse/initializers/auto-load-modules.js.es6 b/app/assets/javascripts/discourse/initializers/auto-load-modules.js.es6
index ae3c15e420..3e1505a5dd 100644
--- a/app/assets/javascripts/discourse/initializers/auto-load-modules.js.es6
+++ b/app/assets/javascripts/discourse/initializers/auto-load-modules.js.es6
@@ -1,4 +1,6 @@
import { registerHelpers } from "discourse-common/lib/helpers";
+import RawHandlebars from "discourse-common/lib/raw-handlebars";
+import { registerRawHelpers } from "discourse-common/lib/raw-handlebars-helpers";
export function autoLoadModules(container, registry) {
Object.keys(requirejs.entries).forEach(entry => {
@@ -10,6 +12,7 @@ export function autoLoadModules(container, registry) {
}
});
registerHelpers(registry);
+ registerRawHelpers(RawHandlebars, Handlebars);
}
export default {
diff --git a/app/assets/javascripts/discourse/initializers/banner.js.es6 b/app/assets/javascripts/discourse/initializers/banner.js.es6
index 46e3899b30..ccec6a95b4 100644
--- a/app/assets/javascripts/discourse/initializers/banner.js.es6
+++ b/app/assets/javascripts/discourse/initializers/banner.js.es6
@@ -1,3 +1,4 @@
+import EmberObject from "@ember/object";
import PreloadStore from "preload-store";
export default {
@@ -5,7 +6,7 @@ export default {
after: "message-bus",
initialize(container) {
- const banner = Ember.Object.create(PreloadStore.get("banner") || {}),
+ const banner = EmberObject.create(PreloadStore.get("banner") || {}),
site = container.lookup("site:main");
site.set("banner", banner);
@@ -16,7 +17,7 @@ export default {
}
messageBus.subscribe("/site/banner", function(ban) {
- site.set("banner", Ember.Object.create(ban || {}));
+ site.set("banner", EmberObject.create(ban || {}));
});
}
};
diff --git a/app/assets/javascripts/discourse/initializers/localization.js.es6 b/app/assets/javascripts/discourse/initializers/localization.js.es6
index fc9eee1536..cbe50e53d5 100644
--- a/app/assets/javascripts/discourse/initializers/localization.js.es6
+++ b/app/assets/javascripts/discourse/initializers/localization.js.es6
@@ -1,5 +1,3 @@
-import PreloadStore from "preload-store";
-
export default {
name: "localization",
after: "inject-objects",
@@ -21,20 +19,9 @@ export default {
}
// Merge any overrides into our object
- const overrides = PreloadStore.get("translationOverrides") || {};
+ const overrides = I18n._overrides || {};
Object.keys(overrides).forEach(k => {
const v = overrides[k];
-
- // Special case: Message format keys are functions
- if (/_MF$/.test(k)) {
- k = k.replace(/^[a-z_]*js\./, "");
- I18n._compiledMFs[k] = new Function(
- "transKey",
- `return (${v})(transKey);`
- );
- return;
- }
-
k = k.replace("admin_js", "js");
const segs = k.split(".");
@@ -52,6 +39,14 @@ export default {
}
});
+ const mfOverrides = I18n._mfOverrides || {};
+ Object.keys(mfOverrides).forEach(k => {
+ const v = mfOverrides[k];
+
+ k = k.replace(/^[a-z_]*js\./, "");
+ I18n._compiledMFs[k] = v;
+ });
+
bootbox.addLocale(I18n.currentLocale(), {
OK: I18n.t("composer.modal_ok"),
CANCEL: I18n.t("composer.modal_cancel"),
diff --git a/app/assets/javascripts/discourse/initializers/mobile.js.es6 b/app/assets/javascripts/discourse/initializers/mobile.js.es6
index a536398e94..b0708fca85 100644
--- a/app/assets/javascripts/discourse/initializers/mobile.js.es6
+++ b/app/assets/javascripts/discourse/initializers/mobile.js.es6
@@ -1,3 +1,4 @@
+import { later } from "@ember/runloop";
import Mobile from "discourse/lib/mobile";
import { setResolverOption } from "discourse-common/resolver";
import { isAppWebview, postRNWebviewMessage } from "discourse/lib/utilities";
@@ -17,7 +18,7 @@ export default {
setResolverOption("mobileView", Mobile.mobileView);
if (isAppWebview()) {
- Ember.run.later(() => {
+ later(() => {
postRNWebviewMessage(
"headerBg",
$(".d-header").css("background-color")
diff --git a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6 b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6
index d3c251bb88..c79a94ceaf 100644
--- a/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6
+++ b/app/assets/javascripts/discourse/initializers/subscribe-user-notifications.js.es6
@@ -1,3 +1,4 @@
+import EmberObject from "@ember/object";
// Subscribes to user events on the message bus
import {
init as initDesktopNotifications,
@@ -10,6 +11,7 @@ import {
unsubscribe as unsubscribePushNotifications,
isPushNotificationsEnabled
} from "discourse/lib/push-notifications";
+import { set } from "@ember/object";
export default {
name: "subscribe-user-notifications",
@@ -82,7 +84,7 @@ export default {
}
oldNotifications.insertAt(
insertPosition,
- Ember.Object.create(lastNotification)
+ EmberObject.create(lastNotification)
);
}
@@ -119,7 +121,7 @@ export default {
});
bus.subscribe("/client_settings", data =>
- Ember.set(siteSettings, data.name, data.value)
+ set(siteSettings, data.name, data.value)
);
bus.subscribe("/refresh_client", data =>
Discourse.set("assetVersion", data)
diff --git a/app/assets/javascripts/discourse/lib/ajax.js.es6 b/app/assets/javascripts/discourse/lib/ajax.js.es6
index cafa6e6f70..40fd85d686 100644
--- a/app/assets/javascripts/discourse/lib/ajax.js.es6
+++ b/app/assets/javascripts/discourse/lib/ajax.js.es6
@@ -1,5 +1,7 @@
+import { run } from "@ember/runloop";
import pageVisible from "discourse/lib/page-visible";
import logout from "discourse/lib/logout";
+import { Promise } from "rsvp";
let _trackView = false;
let _transientHeader = null;
@@ -96,7 +98,7 @@ export function ajax() {
handleRedirect(data);
handleLogoff(xhr);
- Ember.run(() => {
+ run(() => {
Discourse.Site.currentProp(
"isReadOnly",
!!xhr.getResponseHeader("Discourse-Readonly")
@@ -107,7 +109,7 @@ export function ajax() {
data = { result: data, xhr: xhr };
}
- Ember.run(null, resolve, data);
+ run(null, resolve, data);
};
args.error = (xhr, textStatus, errorThrown) => {
@@ -128,7 +130,7 @@ export function ajax() {
xhr.jqTextStatus = textStatus;
xhr.requestedUrl = url;
- Ember.run(null, reject, {
+ run(null, reject, {
jqXHR: xhr,
textStatus: textStatus,
errorThrown: errorThrown
@@ -162,13 +164,13 @@ export function ajax() {
url !== Discourse.getURL("/clicks/track") &&
!Discourse.Session.currentProp("csrfToken")
) {
- promise = new Ember.RSVP.Promise((resolve, reject) => {
+ promise = new Promise((resolve, reject) => {
ajaxObj = updateCsrfToken().then(() => {
performAjax(resolve, reject);
});
});
} else {
- promise = new Ember.RSVP.Promise(performAjax);
+ promise = new Promise(performAjax);
}
promise.abort = () => {
diff --git a/app/assets/javascripts/discourse/lib/autocomplete.js.es6 b/app/assets/javascripts/discourse/lib/autocomplete.js.es6
index 18fc9a98e2..0bcb3331c8 100644
--- a/app/assets/javascripts/discourse/lib/autocomplete.js.es6
+++ b/app/assets/javascripts/discourse/lib/autocomplete.js.es6
@@ -1,3 +1,5 @@
+import { cancel } from "@ember/runloop";
+import { later } from "@ember/runloop";
/**
This is a jQuery plugin to support autocompleting values in our text fields.
@@ -43,7 +45,7 @@ export default function(options) {
if (this.length === 0) return;
if (options === "destroy" || options.updateData) {
- Ember.run.cancel(inputTimeout);
+ cancel(inputTimeout);
$(this)
.off("keyup.autocomplete")
@@ -402,7 +404,7 @@ export default function(options) {
$(this).on("click.autocomplete", () => closeAutocomplete());
$(this).on("paste.autocomplete", () => {
- Ember.run.later(() => me.trigger("keydown"), 50);
+ later(() => me.trigger("keydown"), 50);
});
function checkTriggerRule(opts) {
@@ -455,8 +457,8 @@ export default function(options) {
if (options.allowAny) {
// saves us wiring up a change event as well
- Ember.run.cancel(inputTimeout);
- inputTimeout = Ember.run.later(function() {
+ cancel(inputTimeout);
+ inputTimeout = later(function() {
if (inputSelectedItems.length === 0) {
inputSelectedItems.push("");
}
diff --git a/app/assets/javascripts/discourse/lib/cached-topic-list.js.es6 b/app/assets/javascripts/discourse/lib/cached-topic-list.js.es6
new file mode 100644
index 0000000000..78cd2c0c51
--- /dev/null
+++ b/app/assets/javascripts/discourse/lib/cached-topic-list.js.es6
@@ -0,0 +1,12 @@
+export function findOrResetCachedTopicList(session, filter) {
+ const lastTopicList = session.get("topicList");
+ if (lastTopicList && lastTopicList.filter === filter) {
+ return lastTopicList;
+ } else {
+ session.setProperties({
+ topicList: null,
+ topicListScrollPosition: null
+ });
+ return false;
+ }
+}
diff --git a/app/assets/javascripts/discourse/lib/category-tag-search.js.es6 b/app/assets/javascripts/discourse/lib/category-tag-search.js.es6
index 164839fabf..0b46e05b73 100644
--- a/app/assets/javascripts/discourse/lib/category-tag-search.js.es6
+++ b/app/assets/javascripts/discourse/lib/category-tag-search.js.es6
@@ -3,6 +3,7 @@ import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
import Category from "discourse/models/category";
import { TAG_HASHTAG_POSTFIX } from "discourse/lib/tag-hashtags";
import { SEPARATOR } from "discourse/lib/category-hashtags";
+import { Promise } from "rsvp";
var cache = {};
var cacheTime;
@@ -15,7 +16,7 @@ function updateCache(term, results) {
}
function searchTags(term, categories, limit) {
- return new Ember.RSVP.Promise(resolve => {
+ return new Promise(resolve => {
const clearPromise = setTimeout(() => {
resolve(CANCELLED_STATUS);
}, 5000);
diff --git a/app/assets/javascripts/discourse/lib/clean-dom.js.es6 b/app/assets/javascripts/discourse/lib/clean-dom.js.es6
index 8d83f4d7f8..82cdb2d537 100644
--- a/app/assets/javascripts/discourse/lib/clean-dom.js.es6
+++ b/app/assets/javascripts/discourse/lib/clean-dom.js.es6
@@ -1,3 +1,4 @@
+import { scheduleOnce } from "@ember/runloop";
function _clean() {
if (window.MiniProfiler) {
window.MiniProfiler.pageTransition();
@@ -35,5 +36,5 @@ function _clean() {
}
export function cleanDOM() {
- Ember.run.scheduleOnce("afterRender", _clean);
+ scheduleOnce("afterRender", _clean);
}
diff --git a/app/assets/javascripts/discourse/lib/click-track.js.es6 b/app/assets/javascripts/discourse/lib/click-track.js.es6
index 42a65623a6..12abc76152 100644
--- a/app/assets/javascripts/discourse/lib/click-track.js.es6
+++ b/app/assets/javascripts/discourse/lib/click-track.js.es6
@@ -1,7 +1,9 @@
+import { later } from "@ember/runloop";
import { ajax } from "discourse/lib/ajax";
import DiscourseURL from "discourse/lib/url";
import { wantsNewWindow } from "discourse/lib/intercept-click";
import { selectedText } from "discourse/lib/utilities";
+import { Promise } from "rsvp";
export function isValidLink($link) {
// Do not track:
@@ -95,7 +97,7 @@ export default {
}
}
- let trackPromise = Ember.RSVP.resolve();
+ let trackPromise = Promise.resolve();
if (tracking) {
if (!Ember.testing && navigator.sendBeacon) {
const data = new FormData();
@@ -134,7 +136,7 @@ export default {
$link.attr("href", null);
$link.data("auto-route", true);
- Ember.run.later(() => {
+ later(() => {
$link.removeClass("no-href");
$link.attr("href", $link.data("href"));
$link.data("href", null);
diff --git a/app/assets/javascripts/discourse/lib/debounce.js.es6 b/app/assets/javascripts/discourse/lib/debounce.js.es6
index 6ab2eb1e58..f41b71f0d8 100644
--- a/app/assets/javascripts/discourse/lib/debounce.js.es6
+++ b/app/assets/javascripts/discourse/lib/debounce.js.es6
@@ -1,3 +1,4 @@
+import { debounce } from "@ember/runloop";
/**
Debounce a Javascript function. This means if it's called many times in a time limit it
should only be executed once (at the end of the limit counted from the last call made).
@@ -13,6 +14,6 @@ export default function(func, wait) {
self = this;
args = arguments;
- Ember.run.debounce(null, later, wait);
+ debounce(null, later, wait);
};
}
diff --git a/app/assets/javascripts/discourse/lib/desktop-notifications.js.es6 b/app/assets/javascripts/discourse/lib/desktop-notifications.js.es6
index 41b86bc30e..52c0449285 100644
--- a/app/assets/javascripts/discourse/lib/desktop-notifications.js.es6
+++ b/app/assets/javascripts/discourse/lib/desktop-notifications.js.es6
@@ -1,6 +1,8 @@
+import { later } from "@ember/runloop";
import DiscourseURL from "discourse/lib/url";
import KeyValueStore from "discourse/lib/key-value-store";
import { formatUsername } from "discourse/lib/utilities";
+import { Promise } from "rsvp";
let primaryTab = false;
let liveEnabled = false;
@@ -79,7 +81,7 @@ function confirmNotification() {
const clickEventHandler = () => notification.close();
notification.addEventListener("click", clickEventHandler);
- Ember.run.later(() => {
+ later(() => {
notification.close();
notification.removeEventListener("click", clickEventHandler);
}, 10 * 1000);
@@ -177,7 +179,7 @@ function onNotification(data) {
}
notification.addEventListener("click", clickEventHandler);
- Ember.run.later(() => {
+ later(() => {
notification.close();
notification.removeEventListener("click", clickEventHandler);
}, 10 * 1000);
@@ -188,11 +190,11 @@ function onNotification(data) {
// Wraps Notification.requestPermission in a Promise
function requestPermission() {
if (havePermission === true) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
} else if (havePermission === false) {
- return Ember.RSVP.reject();
+ return Promise.reject();
} else {
- return new Ember.RSVP.Promise(function(resolve, reject) {
+ return new Promise(function(resolve, reject) {
Notification.requestPermission(function(status) {
if (status === "granted") {
resolve();
diff --git a/app/assets/javascripts/discourse/lib/discourse-location.js.es6 b/app/assets/javascripts/discourse/lib/discourse-location.js.es6
index 3843831588..b1238d8d39 100644
--- a/app/assets/javascripts/discourse/lib/discourse-location.js.es6
+++ b/app/assets/javascripts/discourse/lib/discourse-location.js.es6
@@ -1,3 +1,4 @@
+import EmberObject from "@ember/object";
import { defaultHomepage } from "discourse/lib/utilities";
let popstateFired = false;
const supportsHistoryState = window.history && "state" in window.history;
@@ -9,9 +10,9 @@ const popstateCallbacks = [];
@class DiscourseLocation
@namespace Discourse
- @extends Ember.Object
+ @extends @ember/object
*/
-const DiscourseLocation = Ember.Object.extend({
+const DiscourseLocation = EmberObject.extend({
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
index e051f479ff..991644737a 100644
--- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
+++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
@@ -1,3 +1,5 @@
+import { run } from "@ember/runloop";
+import { later } from "@ember/runloop";
import DiscourseURL from "discourse/lib/url";
import Composer from "discourse/models/composer";
import { minimumOffset } from "discourse/lib/offset-calculator";
@@ -140,7 +142,7 @@ export default {
quoteReply() {
this.sendToSelectedPost("replyToPost");
// lazy but should work for now
- Ember.run.later(() => $(".d-editor .quote").click(), 500);
+ later(() => $(".d-editor .quote").click(), 500);
return false;
},
@@ -210,7 +212,7 @@ export default {
},
showPageSearch(event) {
- Ember.run(() => {
+ run(() => {
this.appEvents.trigger("header:keyboard-trigger", {
type: "page-search",
event
@@ -219,7 +221,7 @@ export default {
},
printTopic(event) {
- Ember.run(() => {
+ run(() => {
if ($(".container.posts").length) {
event.preventDefault(); // We need to stop printing the current page in Firefox
this.container.lookup("controller:topic").print();
@@ -241,7 +243,7 @@ export default {
this.container.lookup("controller:composer").open({
action: Composer.CREATE_TOPIC,
- draftKey: Composer.CREATE_TOPIC
+ draftKey: Composer.NEW_TOPIC_KEY
});
},
diff --git a/app/assets/javascripts/discourse/lib/link-category-hashtags.js.es6 b/app/assets/javascripts/discourse/lib/link-category-hashtags.js.es6
index d43b0f4a83..7179f234f1 100644
--- a/app/assets/javascripts/discourse/lib/link-category-hashtags.js.es6
+++ b/app/assets/javascripts/discourse/lib/link-category-hashtags.js.es6
@@ -1,3 +1,4 @@
+import { schedule } from "@ember/runloop";
import { ajax } from "discourse/lib/ajax";
import { replaceSpan } from "discourse/lib/category-hashtags";
@@ -7,7 +8,7 @@ const testedKey = "tested";
const testedClass = `hashtag-${testedKey}`;
function updateFound($hashtags, categorySlugs) {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$hashtags.each((index, hashtag) => {
const categorySlug = categorySlugs[index];
const link = validCategoryHashtags[categorySlug];
diff --git a/app/assets/javascripts/discourse/lib/link-mentions.js.es6 b/app/assets/javascripts/discourse/lib/link-mentions.js.es6
index 07f37388e4..68d0b8b5d6 100644
--- a/app/assets/javascripts/discourse/lib/link-mentions.js.es6
+++ b/app/assets/javascripts/discourse/lib/link-mentions.js.es6
@@ -1,3 +1,4 @@
+import { scheduleOnce } from "@ember/runloop";
import { ajax } from "discourse/lib/ajax";
import { userPath } from "discourse/lib/url";
import { formatUsername } from "discourse/lib/utilities";
@@ -39,7 +40,7 @@ const checked = {};
const cannotSee = [];
function updateFound($mentions, usernames) {
- Ember.run.scheduleOnce("afterRender", function() {
+ scheduleOnce("afterRender", function() {
$mentions.each((i, e) => {
const $e = $(e);
const username = usernames[i];
diff --git a/app/assets/javascripts/discourse/lib/link-tag-hashtag.js.es6 b/app/assets/javascripts/discourse/lib/link-tag-hashtag.js.es6
index a0b2c95c46..5aa3f6d612 100644
--- a/app/assets/javascripts/discourse/lib/link-tag-hashtag.js.es6
+++ b/app/assets/javascripts/discourse/lib/link-tag-hashtag.js.es6
@@ -1,3 +1,4 @@
+import { schedule } from "@ember/runloop";
import { ajax } from "discourse/lib/ajax";
import { replaceSpan } from "discourse/lib/category-hashtags";
import { TAG_HASHTAG_POSTFIX } from "discourse/lib/tag-hashtags";
@@ -7,7 +8,7 @@ const checkedTagHashtags = [];
const testedClass = "tag-hashtag-tested";
function updateFound($hashtags, tagValues) {
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
$hashtags.each((index, hashtag) => {
const tagValue = tagValues[index];
const link = validTagHashtags[tagValue];
diff --git a/app/assets/javascripts/discourse/lib/load-script.js.es6 b/app/assets/javascripts/discourse/lib/load-script.js.es6
index 34b3f2897b..1efec2ea78 100644
--- a/app/assets/javascripts/discourse/lib/load-script.js.es6
+++ b/app/assets/javascripts/discourse/lib/load-script.js.es6
@@ -1,4 +1,7 @@
+import { run } from "@ember/runloop";
import { ajax } from "discourse/lib/ajax";
+import { Promise } from "rsvp";
+
const _loaded = {};
const _loading = {};
@@ -22,7 +25,7 @@ function loadWithTag(path, cb) {
) {
s = s.onload = s.onreadystatechange = null;
if (!abort) {
- Ember.run(null, cb);
+ run(null, cb);
}
}
};
@@ -37,7 +40,7 @@ export function loadCSS(url) {
export default function loadScript(url, opts) {
// TODO: Remove this once plugins have been updated not to use it:
if (url === "defer/html-sanitizer-bundle") {
- return Ember.RSVP.Promise.resolve();
+ return Promise.resolve();
}
opts = opts || {};
@@ -54,7 +57,7 @@ export default function loadScript(url, opts) {
}
});
- return new Ember.RSVP.Promise(function(resolve) {
+ return new Promise(function(resolve) {
// If we already loaded this url
if (_loaded[url]) {
return resolve();
@@ -64,7 +67,7 @@ export default function loadScript(url, opts) {
}
let done;
- _loading[url] = new Ember.RSVP.Promise(function(_done) {
+ _loading[url] = new Promise(function(_done) {
done = _done;
});
diff --git a/app/assets/javascripts/discourse/lib/logout.js.es6 b/app/assets/javascripts/discourse/lib/logout.js.es6
index 5e81d738e3..09986e892b 100644
--- a/app/assets/javascripts/discourse/lib/logout.js.es6
+++ b/app/assets/javascripts/discourse/lib/logout.js.es6
@@ -1,3 +1,4 @@
+import { isEmpty } from "@ember/utils";
export default function logout(siteSettings, keyValueStore) {
if (!siteSettings || !keyValueStore) {
const container = Discourse.__container__;
@@ -8,7 +9,7 @@ export default function logout(siteSettings, keyValueStore) {
keyValueStore.abandonLocal();
const redirect = siteSettings.logout_redirect;
- if (Ember.isEmpty(redirect)) {
+ if (isEmpty(redirect)) {
window.location = Discourse.getURL("/");
} else {
window.location.href = redirect;
diff --git a/app/assets/javascripts/discourse/lib/page-tracker.js.es6 b/app/assets/javascripts/discourse/lib/page-tracker.js.es6
index d7577ed5ae..4acbdc4ea3 100644
--- a/app/assets/javascripts/discourse/lib/page-tracker.js.es6
+++ b/app/assets/javascripts/discourse/lib/page-tracker.js.es6
@@ -1,3 +1,4 @@
+import { next } from "@ember/runloop";
let _started = false;
let cache = {};
let transitionCount = 0;
@@ -31,7 +32,7 @@ export function startPageTracking(router, appEvents) {
// Refreshing the title is debounced, so we need to trigger this in the
// next runloop to have the correct title.
- Ember.run.next(() => {
+ next(() => {
let title = Discourse.get("_docTitle");
appEvents.trigger("page:changed", {
diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6
index 4cf670b3de..88f2d7381d 100644
--- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6
+++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6
@@ -43,9 +43,10 @@ import Sharing from "discourse/lib/sharing";
import { addComposerUploadHandler } from "discourse/components/composer-editor";
import { addCategorySortCriteria } from "discourse/components/edit-category-settings";
import { queryRegistry } from "discourse/widgets/widget";
+import Composer from "discourse/models/composer";
// If you add any methods to the API ensure you bump up this number
-const PLUGIN_API_VERSION = "0.8.32";
+const PLUGIN_API_VERSION = "0.8.36";
class PluginApi {
constructor(version, container) {
@@ -424,45 +425,45 @@ class PluginApi {
}
/**
- Called whenever the "page" changes. This allows us to set up analytics
- and other tracking.
+ Called whenever the "page" changes. This allows us to set up analytics
+ and other tracking.
- To get notified when the page changes, you can install a hook like so:
+ To get notified when the page changes, you can install a hook like so:
- ```javascript
- api.onPageChange((url, title) => {
+ ```javascript
+ api.onPageChange((url, title) => {
console.log('the page changed to: ' + url + ' and title ' + title);
});
- ```
- **/
+ ```
+ **/
onPageChange(fn) {
this.onAppEvent("page:changed", data => fn(data.url, data.title));
}
/**
- Listen for a triggered `AppEvent` from Discourse.
+ Listen for a triggered `AppEvent` from Discourse.
- ```javascript
- api.onAppEvent('inserted-custom-html', () => {
+ ```javascript
+ api.onAppEvent('inserted-custom-html', () => {
console.log('a custom footer was rendered');
});
- ```
- **/
+ ```
+ **/
onAppEvent(name, fn) {
const appEvents = this._lookupContainer("service:app-events");
appEvents && appEvents.on(name, fn);
}
/**
- Registers a function to generate custom avatar CSS classes
- for a particular user.
+ Registers a function to generate custom avatar CSS classes
+ for a particular user.
- Takes a function that will accept a user as a parameter
- and return an array of CSS classes to apply.
+ Takes a function that will accept a user as a parameter
+ and return an array of CSS classes to apply.
- ```javascript
- api.customUserAvatarClasses(user => {
- if (Ember.get(user, 'primary_group_name') === 'managers') {
+ ```javascript
+ api.customUserAvatarClasses(user => {
+ if (get(user, 'primary_group_name') === 'managers') {
return ['managers'];
}
});
@@ -715,7 +716,7 @@ class PluginApi {
/**
*
- * Adds a new item in the navigation bar.
+ * Adds a new item in the navigation bar. Returns the NavItem object created.
*
* Example:
*
@@ -728,14 +729,20 @@ class PluginApi {
* An optional `customFilter` callback can be included to not display the
* nav item on certain routes
*
+ * An optional `init` callback can be included to run custom code on menu
+ * init
+ *
* Example:
*
* addNavigationBarItem({
* name: "link-to-bugs-category",
* displayName: "bugs"
* href: "/c/bugs",
+ * init: (navItem, category) => { if (category) { navItem.set("category", category) } }
* customFilter: (category, args, router) => { category && category.name !== 'bug' }
- * customHref: (category, args, router) => { if (category && category.name) === 'not-a-bug') "/a-feature"; }
+ * customHref: (category, args, router) => { if (category && category.name) === 'not-a-bug') "/a-feature"; },
+ * before: "top",
+ * forceActive(category, args, router) => router.currentURL === "/a/b/c/d";
* })
*/
addNavigationBarItem(item) {
@@ -762,7 +769,23 @@ class PluginApi {
};
}
- addNavItem(item);
+ const forceActive = item.forceActive;
+ if (forceActive) {
+ const router = this.container.lookup("service:router");
+ item.forceActive = function(category, args) {
+ return forceActive(category, args, router);
+ };
+ }
+
+ const init = item.init;
+ if (init) {
+ const router = this.container.lookup("service:router");
+ item.init = function(navItem, category, args) {
+ init(navItem, category, args, router);
+ };
+ }
+
+ return addNavItem(item);
}
}
@@ -790,7 +813,7 @@ class PluginApi {
*
* Example:
*
- * modifySelectKit("topic-footer-mobile-dropdown").appendContent(() => [{
+ * api.modifySelectKit("topic-footer-mobile-dropdown").appendContent(() => [{
* name: "discourse",
* id: 1
* }])
@@ -806,7 +829,7 @@ class PluginApi {
*
* Example:
*
- * addGTMPageChangedCallback( gtmData => gtmData.locale = I18n.currentLocale() )
+ * api.addGTMPageChangedCallback( gtmData => gtmData.locale = I18n.currentLocale() )
*
*/
addGTMPageChangedCallback(fn) {
@@ -820,7 +843,7 @@ class PluginApi {
* Example:
*
* // read /discourse/lib/sharing.js.es6 for options
- * addSharingSource(options)
+ * api.addSharingSource(options)
*
*/
addSharingSource(options) {
@@ -836,14 +859,43 @@ class PluginApi {
*
* Example:
*
- * addComposerUploadHandler(["mp4", "mov"], (file, editor) => {
- * console.log("Handling upload for", file.name);
+ * api.addComposerUploadHandler(["mp4", "mov"], (file, editor) => {
+ * console.log("Handling upload for", file.name);
* })
*/
addComposerUploadHandler(extensions, method) {
addComposerUploadHandler(extensions, method);
}
+ /**
+ * Registers a "beforeSave" function on the composer. This allows you to
+ * implement custom logic that will happen before the user makes a post.
+ *
+ * Example:
+ *
+ * api.composerBeforeSave(() => {
+ * console.log("Before saving, do something!");
+ * })
+ */
+ composerBeforeSave(method) {
+ Composer.reopen({ beforeSave: method });
+ }
+
+ /**
+ * Adds a field to draft serializer
+ *
+ * Example:
+ *
+ * api.serializeToDraft('key_set_in_model', 'field_name_in_payload');
+ *
+ * to keep both of them same
+ * api.serializeToDraft('field_name');
+ *
+ */
+ serializeToDraft(fieldName, property) {
+ Composer.serializeToDraft(fieldName, property);
+ }
+
/**
* Registers a criteria that can be used as default topic order on category
* pages.
diff --git a/app/assets/javascripts/discourse/lib/posts-with-placeholders.js.es6 b/app/assets/javascripts/discourse/lib/posts-with-placeholders.js.es6
index 03271c6d6b..d1b2092445 100644
--- a/app/assets/javascripts/discourse/lib/posts-with-placeholders.js.es6
+++ b/app/assets/javascripts/discourse/lib/posts-with-placeholders.js.es6
@@ -1,10 +1,11 @@
+import EmberObject from "@ember/object";
import { default as computed } from "ember-addons/ember-computed-decorators";
export function Placeholder(viewName) {
this.viewName = viewName;
}
-export default Ember.Object.extend(Ember.Array, {
+export default EmberObject.extend(Ember.Array, {
posts: null,
_appendingIds: null,
diff --git a/app/assets/javascripts/discourse/lib/pwa-utils.js.es6 b/app/assets/javascripts/discourse/lib/pwa-utils.js.es6
index c1833da32b..1e2c901bd6 100644
--- a/app/assets/javascripts/discourse/lib/pwa-utils.js.es6
+++ b/app/assets/javascripts/discourse/lib/pwa-utils.js.es6
@@ -1,6 +1,8 @@
+import { Promise } from "rsvp";
+
export function nativeShare(data) {
const caps = Discourse.__container__.lookup("capabilities:main");
- return new Ember.RSVP.Promise((resolve, reject) => {
+ return new Promise((resolve, reject) => {
if (!(caps.isIOS || caps.isAndroid || caps.isWinphone)) {
reject();
return;
diff --git a/app/assets/javascripts/discourse/lib/render-topic-featured-link.js.es6 b/app/assets/javascripts/discourse/lib/render-topic-featured-link.js.es6
index 7fa722a28d..bcf13b115a 100644
--- a/app/assets/javascripts/discourse/lib/render-topic-featured-link.js.es6
+++ b/app/assets/javascripts/discourse/lib/render-topic-featured-link.js.es6
@@ -21,7 +21,7 @@ export function extractLinkMeta(topic) {
target: target,
href,
domain: topic.get("featured_link_root_domain"),
- rel: "nofollow"
+ rel: "nofollow ugc"
};
if (_decorators.length) {
diff --git a/app/assets/javascripts/discourse/lib/safari-hacks.js.es6 b/app/assets/javascripts/discourse/lib/safari-hacks.js.es6
index 1fb5318045..afb55f7f8b 100644
--- a/app/assets/javascripts/discourse/lib/safari-hacks.js.es6
+++ b/app/assets/javascripts/discourse/lib/safari-hacks.js.es6
@@ -1,3 +1,4 @@
+import { later } from "@ember/runloop";
import debounce from "discourse/lib/debounce";
import {
safariHacksDisabled,
@@ -94,10 +95,7 @@ function positioningWorkaround($fixedElement) {
if (!iOSWithVisualViewport()) {
fixedElement.style.height = oldHeight;
- Ember.run.later(
- () => $(fixedElement).removeClass("no-transition"),
- 500
- );
+ later(() => $(fixedElement).removeClass("no-transition"), 500);
}
$(window).scrollTop(originalScrollTop);
@@ -114,9 +112,16 @@ function positioningWorkaround($fixedElement) {
// document.activeElement is also unreliable (iOS does not mark buttons as focused)
// so instead, we store the last touched element and check against it
+ // cancel blur event if user is:
+ // - switching to another iOS app
+ // - invoking a select-kit dropdown
+ // - invoking mentions
+ // - invoking a toolbar button
if (
lastTouchedElement &&
- ($(lastTouchedElement).hasClass("select-kit-header") ||
+ (document.visibilityState === "hidden" ||
+ $(lastTouchedElement).hasClass("select-kit-header") ||
+ $(lastTouchedElement).closest(".autocomplete").length ||
["span", "svg", "button"].includes(
lastTouchedElement.nodeName.toLowerCase()
))
diff --git a/app/assets/javascripts/discourse/lib/screen-track.js.es6 b/app/assets/javascripts/discourse/lib/screen-track.js.es6
index a36b15cb21..314e1fac0a 100644
--- a/app/assets/javascripts/discourse/lib/screen-track.js.es6
+++ b/app/assets/javascripts/discourse/lib/screen-track.js.es6
@@ -1,3 +1,4 @@
+import { bind } from "@ember/runloop";
import { ajax } from "discourse/lib/ajax";
// We use this class to track how long posts in a topic are on the screen.
@@ -26,7 +27,7 @@ export default class {
// Create an interval timer if we don't have one.
if (!this._interval) {
this._interval = setInterval(() => this.tick(), 1000);
- this._boundScrolled = Ember.run.bind(this, this.scrolled);
+ this._boundScrolled = bind(this, this.scrolled);
$(window).on("scroll.screentrack", this._boundScrolled);
}
diff --git a/app/assets/javascripts/discourse/lib/search.js.es6 b/app/assets/javascripts/discourse/lib/search.js.es6
index b8e7dd0546..2824268e66 100644
--- a/app/assets/javascripts/discourse/lib/search.js.es6
+++ b/app/assets/javascripts/discourse/lib/search.js.es6
@@ -1,3 +1,5 @@
+import { isEmpty } from "@ember/utils";
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import { findRawTemplate } from "discourse/lib/raw-templates";
import Category from "discourse/models/category";
@@ -52,7 +54,7 @@ export function translateResults(results, opts) {
const fullName = Handlebars.Utils.escapeExpression(
group.full_name || group.display_name
);
- const flairUrl = Ember.isEmpty(group.flair_url)
+ const flairUrl = isEmpty(group.flair_url)
? null
: Handlebars.Utils.escapeExpression(group.flair_url);
const flairColor = Handlebars.Utils.escapeExpression(group.flair_color);
@@ -75,7 +77,7 @@ export function translateResults(results, opts) {
results.tags = results.tags
.map(function(tag) {
const tagName = Handlebars.Utils.escapeExpression(tag.name);
- return Ember.Object.create({
+ return EmberObject.create({
id: tagName,
url: Discourse.getURL("/tags/" + tagName)
});
@@ -127,7 +129,7 @@ export function translateResults(results, opts) {
!results.categories.length
);
- return noResults ? null : Ember.Object.create(results);
+ return noResults ? null : EmberObject.create(results);
}
export function searchForTerm(term, opts) {
diff --git a/app/assets/javascripts/discourse/lib/show-modal.js.es6 b/app/assets/javascripts/discourse/lib/show-modal.js.es6
index 8cf5a2b0be..968f1e399d 100644
--- a/app/assets/javascripts/discourse/lib/show-modal.js.es6
+++ b/app/assets/javascripts/discourse/lib/show-modal.js.es6
@@ -1,3 +1,5 @@
+import { dasherize } from "@ember/string";
+
export default function(name, opts) {
opts = opts || {};
const container = Discourse.__container__;
@@ -13,7 +15,7 @@ export default function(name, opts) {
modalController.set("name", controllerName);
let controller = container.lookup("controller:" + controllerName);
- const templateName = opts.templateName || Ember.String.dasherize(name);
+ const templateName = opts.templateName || dasherize(name);
const renderArgs = { into: "modal", outlet: "modalBody" };
if (controller) {
diff --git a/app/assets/javascripts/discourse/lib/static-route-builder.js.es6 b/app/assets/javascripts/discourse/lib/static-route-builder.js.es6
index efc97411c0..8baa97fb4d 100644
--- a/app/assets/javascripts/discourse/lib/static-route-builder.js.es6
+++ b/app/assets/javascripts/discourse/lib/static-route-builder.js.es6
@@ -1,3 +1,4 @@
+import DiscourseRoute from "discourse/routes/discourse";
import StaticPage from "discourse/models/static-page";
import { default as DiscourseURL, jumpToElement } from "discourse/lib/url";
@@ -8,7 +9,7 @@ const configs = {
};
export default function(page) {
- return Discourse.Route.extend({
+ return DiscourseRoute.extend({
renderTemplate() {
this.render("static");
},
diff --git a/app/assets/javascripts/discourse/lib/text.js.es6 b/app/assets/javascripts/discourse/lib/text.js.es6
index cb02036ced..2767426c09 100644
--- a/app/assets/javascripts/discourse/lib/text.js.es6
+++ b/app/assets/javascripts/discourse/lib/text.js.es6
@@ -4,6 +4,7 @@ import WhiteLister from "pretty-text/white-lister";
import { sanitize as textSanitize } from "pretty-text/sanitizer";
import loadScript from "discourse/lib/load-script";
import { formatUsername } from "discourse/lib/utilities";
+import { Promise } from "rsvp";
function getOpts(opts) {
const siteSettings = Discourse.__container__.lookup("site-settings:main"),
@@ -51,7 +52,7 @@ function loadMarkdownIt() {
console.error(e);
});
} else {
- return Ember.RSVP.Promise.resolve();
+ return Promise.resolve();
}
}
diff --git a/app/assets/javascripts/discourse/lib/throttle.js.es6 b/app/assets/javascripts/discourse/lib/throttle.js.es6
index 2e8673203b..05daa36c5a 100644
--- a/app/assets/javascripts/discourse/lib/throttle.js.es6
+++ b/app/assets/javascripts/discourse/lib/throttle.js.es6
@@ -1,3 +1,4 @@
+import { throttle } from "@ember/runloop";
/**
Throttle a Javascript function. This means if it's called many times in a time limit it
should only be executed one time at most during this time limit
@@ -13,6 +14,6 @@ export default function(func, spacing, immediate) {
self = this;
args = arguments;
- Ember.run.throttle(null, later, spacing, immediate);
+ throttle(null, later, spacing, immediate);
};
}
diff --git a/app/assets/javascripts/discourse/lib/transform-post.js.es6 b/app/assets/javascripts/discourse/lib/transform-post.js.es6
index 5f882d8a93..e6583cf8f6 100644
--- a/app/assets/javascripts/discourse/lib/transform-post.js.es6
+++ b/app/assets/javascripts/discourse/lib/transform-post.js.es6
@@ -1,3 +1,4 @@
+import { isEmpty } from "@ember/utils";
import { userPath } from "discourse/lib/url";
const _additionalAttributes = [];
@@ -48,7 +49,7 @@ export function transformBasicPost(post) {
showFlagDelete: false,
canRecover: post.can_recover,
canEdit: post.can_edit,
- canFlag: !Ember.isEmpty(post.get("flagsAvailable")),
+ canFlag: !isEmpty(post.get("flagsAvailable")),
canReviewTopic: false,
reviewableId: post.reviewable_id,
reviewableScoreCount: post.reviewable_score_count,
diff --git a/app/assets/javascripts/discourse/lib/url.js.es6 b/app/assets/javascripts/discourse/lib/url.js.es6
index 34bb600e07..71986d4d29 100644
--- a/app/assets/javascripts/discourse/lib/url.js.es6
+++ b/app/assets/javascripts/discourse/lib/url.js.es6
@@ -1,3 +1,7 @@
+import { isEmpty } from "@ember/utils";
+import EmberObject from "@ember/object";
+import { next } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
import offsetCalculator from "discourse/lib/offset-calculator";
import LockOn from "discourse/lib/lock-on";
import { defaultHomepage } from "discourse/lib/utilities";
@@ -59,13 +63,13 @@ export function groupPath(subPath) {
let _jumpScheduled = false;
export function jumpToElement(elementId) {
- if (_jumpScheduled || Ember.isEmpty(elementId)) {
+ if (_jumpScheduled || isEmpty(elementId)) {
return;
}
const selector = `#${elementId}, a[name=${elementId}]`;
_jumpScheduled = true;
- Ember.run.schedule("afterRender", function() {
+ schedule("afterRender", function() {
const lockon = new LockOn(selector, {
finished() {
_jumpScheduled = false;
@@ -77,7 +81,7 @@ export function jumpToElement(elementId) {
let _transitioning = false;
-const DiscourseURL = Ember.Object.extend({
+const DiscourseURL = EmberObject.extend({
isJumpScheduled() {
return _transitioning || _jumpScheduled;
},
@@ -89,7 +93,7 @@ const DiscourseURL = Ember.Object.extend({
_transitioning = postNumber > 1;
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
let elementId;
let holder;
@@ -155,7 +159,7 @@ const DiscourseURL = Ember.Object.extend({
// Always use replaceState in the next runloop to prevent weird routes changing
// while URLs are loading. For example, while a topic loads it sets `currentPost`
// which triggers a replaceState even though the topic hasn't fully loaded yet!
- Ember.run.next(() => {
+ next(() => {
const location = DiscourseURL.get("router.location");
if (location && location.replaceURL) {
location.replaceURL(path);
@@ -188,7 +192,7 @@ const DiscourseURL = Ember.Object.extend({
routeTo(path, opts) {
opts = opts || {};
- if (Ember.isEmpty(path)) {
+ if (isEmpty(path)) {
return;
}
@@ -249,7 +253,7 @@ const DiscourseURL = Ember.Object.extend({
path = rewritePath(path);
if (typeof opts.afterRouteComplete === "function") {
- Ember.run.schedule("afterRender", opts.afterRouteComplete);
+ schedule("afterRender", opts.afterRouteComplete);
}
if (this.navigatedToPost(oldPath, path, opts)) {
diff --git a/app/assets/javascripts/discourse/lib/user-search.js.es6 b/app/assets/javascripts/discourse/lib/user-search.js.es6
index 1cb70232e9..63fbb2da71 100644
--- a/app/assets/javascripts/discourse/lib/user-search.js.es6
+++ b/app/assets/javascripts/discourse/lib/user-search.js.es6
@@ -2,6 +2,7 @@ import debounce from "discourse/lib/debounce";
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
import { userPath } from "discourse/lib/url";
import { emailValid } from "discourse/lib/utilities";
+import { Promise } from "rsvp";
var cache = {},
cacheKey,
@@ -26,11 +27,13 @@ function performSearch(
return;
}
- // I am not strongly against unconditionally returning
- // however this allows us to return a list of probable
- // users we want to mention, early on a topic
- if (term === "" && !topicId && !categoryId) {
- return [];
+ const eagerComplete = term === "" && !!(topicId || categoryId);
+
+ if (term === "" && !eagerComplete) {
+ // The server returns no results in this case, so no point checking
+ // do not return empty list, because autocomplete will get terminated
+ resultsFn(CANCELLED_STATUS);
+ return;
}
// need to be able to cancel this
@@ -51,6 +54,18 @@ function performSearch(
oldSearch
.then(function(r) {
+ const hasResults = !!(
+ (r.users && r.users.length) ||
+ (r.groups && r.groups.length) ||
+ (r.emails && r.emails.length)
+ );
+
+ if (eagerComplete && !hasResults) {
+ // we are trying to eager load, but received no results
+ // do not return empty list, because autocomplete will get terminated
+ r = CANCELLED_STATUS;
+ }
+
cache[term] = r;
cacheTime = new Date();
// If there is a newer search term, return null
@@ -152,7 +167,7 @@ export default function userSearch(options) {
currentTerm = term;
- return new Ember.RSVP.Promise(function(resolve) {
+ return new Promise(function(resolve) {
const newCacheKey = `${topicId}-${categoryId}`;
if (new Date() - cacheTime > 30000 || cacheKey !== newCacheKey) {
diff --git a/app/assets/javascripts/discourse/mixins/badge-select-controller.js.es6 b/app/assets/javascripts/discourse/mixins/badge-select-controller.js.es6
deleted file mode 100644
index 449030dad2..0000000000
--- a/app/assets/javascripts/discourse/mixins/badge-select-controller.js.es6
+++ /dev/null
@@ -1,39 +0,0 @@
-import Badge from "discourse/models/badge";
-import computed from "ember-addons/ember-computed-decorators";
-
-export default Ember.Mixin.create({
- saving: false,
- saved: false,
-
- @computed("filteredList")
- selectableUserBadges(items) {
- items = _.uniq(items, false, function(e) {
- return e.get("badge.name");
- });
- items.unshiftObject(
- Ember.Object.create({
- badge: Badge.create({ name: I18n.t("badges.none") })
- })
- );
- return items;
- },
-
- @computed("saving")
- savingStatus(saving) {
- return saving ? I18n.t("saving") : I18n.t("save");
- },
-
- @computed("selectedUserBadgeId")
- selectedUserBadge(selectedUserBadgeId) {
- selectedUserBadgeId = parseInt(selectedUserBadgeId);
- let selectedUserBadge = null;
- this.selectableUserBadges.forEach(function(userBadge) {
- if (userBadge.get("id") === selectedUserBadgeId) {
- selectedUserBadge = userBadge;
- }
- });
- return selectedUserBadge;
- },
-
- disableSave: Ember.computed.alias("saving")
-});
diff --git a/app/assets/javascripts/discourse/mixins/buffered-content.js.es6 b/app/assets/javascripts/discourse/mixins/buffered-content.js.es6
index 36f6de6071..08723e1486 100644
--- a/app/assets/javascripts/discourse/mixins/buffered-content.js.es6
+++ b/app/assets/javascripts/discourse/mixins/buffered-content.js.es6
@@ -1,8 +1,11 @@
+import EmberObjectProxy from "@ember/object/proxy";
+import Mixin from "@ember/object/mixin";
+
/* global BufferedProxy: true */
export function bufferedProperty(property) {
const mixin = {
buffered: Ember.computed(property, function() {
- return Ember.ObjectProxy.extend(BufferedProxy).create({
+ return EmberObjectProxy.extend(BufferedProxy).create({
content: this.get(property)
});
}),
@@ -19,7 +22,7 @@ export function bufferedProperty(property) {
// It's a good idea to null out fields when declaring objects
mixin.property = null;
- return Ember.Mixin.create(mixin);
+ return Mixin.create(mixin);
}
export default bufferedProperty("content");
diff --git a/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6 b/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6
index 411dfb6688..311e47661d 100644
--- a/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6
+++ b/app/assets/javascripts/discourse/mixins/bulk-topic-selection.js.es6
@@ -1,11 +1,13 @@
+import { alias } from "@ember/object/computed";
import { NotificationLevels } from "discourse/lib/notification-levels";
import { on } from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
bulkSelectEnabled: false,
selected: null,
- canBulkSelect: Ember.computed.alias("currentUser.staff"),
+ canBulkSelect: alias("currentUser.staff"),
@on("init")
resetSelected() {
diff --git a/app/assets/javascripts/discourse/mixins/can-check-emails.js.es6 b/app/assets/javascripts/discourse/mixins/can-check-emails.js.es6
index a7eb59fe7b..9e203da744 100644
--- a/app/assets/javascripts/discourse/mixins/can-check-emails.js.es6
+++ b/app/assets/javascripts/discourse/mixins/can-check-emails.js.es6
@@ -1,14 +1,13 @@
+import { and, alias, or } from "@ember/object/computed";
import { propertyEqual, setting } from "discourse/lib/computed";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
isCurrentUser: propertyEqual("model.id", "currentUser.id"),
showEmailOnProfile: setting("moderators_view_emails"),
- canStaffCheckEmails: Ember.computed.and(
- "showEmailOnProfile",
- "currentUser.staff"
- ),
- canAdminCheckEmails: Ember.computed.alias("currentUser.admin"),
- canCheckEmails: Ember.computed.or(
+ canStaffCheckEmails: and("showEmailOnProfile", "currentUser.staff"),
+ canAdminCheckEmails: alias("currentUser.admin"),
+ canCheckEmails: or(
"isCurrentUser",
"canStaffCheckEmails",
"canAdminCheckEmails"
diff --git a/app/assets/javascripts/discourse/mixins/card-contents-base.js.es6 b/app/assets/javascripts/discourse/mixins/card-contents-base.js.es6
index 212278f2e0..e9c0c0df56 100644
--- a/app/assets/javascripts/discourse/mixins/card-contents-base.js.es6
+++ b/app/assets/javascripts/discourse/mixins/card-contents-base.js.es6
@@ -1,14 +1,19 @@
+import { alias, match } from "@ember/object/computed";
+import { throttle } from "@ember/runloop";
+import { next } from "@ember/runloop";
+import { schedule } from "@ember/runloop";
import { wantsNewWindow } from "discourse/lib/intercept-click";
import afterTransition from "discourse/lib/after-transition";
import DiscourseURL from "discourse/lib/url";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
elementId: null, //click detection added for data-{elementId}
triggeringLinkClass: null, //the classname where this card should appear
_showCallback: null, //username, $target - load up data for when show is called, should call this._positionCard($target) when it's done.
- postStream: Ember.computed.alias("topic.postStream"),
- viewingTopic: Ember.computed.match("currentPath", /^topic\./),
+ postStream: alias("topic.postStream"),
+ viewingTopic: match("currentPath", /^topic\./),
visible: false,
username: null,
@@ -142,7 +147,7 @@ export default Ember.Mixin.create({
_bindMobileScroll() {
const mobileScrollEvent = this.mobileScrollEvent;
const onScroll = () => {
- Ember.run.throttle(this, this._close, 1000);
+ throttle(this, this._close, 1000);
};
$(window).on(mobileScrollEvent, onScroll);
@@ -171,7 +176,7 @@ export default Ember.Mixin.create({
let verticalAdjustments = 0;
- Ember.run.schedule("afterRender", () => {
+ schedule("afterRender", () => {
if (target) {
if (!this.site.mobileView) {
let position = target.offset();
@@ -245,7 +250,7 @@ export default Ember.Mixin.create({
// note: we DO NOT use afterRender here cause _positionCard may
// run afterwards, if we allowed this to happen the usercard
// may be offscreen and we may scroll all the way to it on focus
- Ember.run.next(null, () => {
+ next(null, () => {
const firstLink = this.element.querySelector("a");
firstLink && firstLink.focus();
});
diff --git a/app/assets/javascripts/discourse/mixins/cleans-up.js.es6 b/app/assets/javascripts/discourse/mixins/cleans-up.js.es6
index 09d469af1c..ffbaf7a9ee 100644
--- a/app/assets/javascripts/discourse/mixins/cleans-up.js.es6
+++ b/app/assets/javascripts/discourse/mixins/cleans-up.js.es6
@@ -1,11 +1,14 @@
+import { on } from "@ember/object/evented";
+import Mixin from "@ember/object/mixin";
+
// Include this mixin if you want to be notified when the dom should be
// cleaned (usually on route change.)
-export default Ember.Mixin.create({
- _initializeChooser: function() {
+export default Mixin.create({
+ _initializeChooser: on("didInsertElement", function() {
this.appEvents.on("dom:clean", this, "cleanUp");
- }.on("didInsertElement"),
+ }),
- _clearChooser: function() {
+ _clearChooser: on("willDestroyElement", function() {
this.appEvents.off("dom:clean", this, "cleanUp");
- }.on("willDestroyElement")
+ })
});
diff --git a/app/assets/javascripts/discourse/mixins/docking.js.es6 b/app/assets/javascripts/discourse/mixins/docking.js.es6
index 800898ae70..3df9f80eda 100644
--- a/app/assets/javascripts/discourse/mixins/docking.js.es6
+++ b/app/assets/javascripts/discourse/mixins/docking.js.es6
@@ -1,3 +1,6 @@
+import Mixin from "@ember/object/mixin";
+import { debounce } from "@ember/runloop";
+
const helper = {
offset() {
const mainOffset = $("#main").offset();
@@ -6,13 +9,13 @@ const helper = {
}
};
-export default Ember.Mixin.create({
+export default Mixin.create({
queueDockCheck: null,
init() {
this._super(...arguments);
this.queueDockCheck = () => {
- Ember.run.debounce(this, this.safeDockCheck, 5);
+ debounce(this, this.safeDockCheck, 5);
};
},
diff --git a/app/assets/javascripts/discourse/mixins/grant-badge-controller.js.es6 b/app/assets/javascripts/discourse/mixins/grant-badge-controller.js.es6
index cc0d82fd87..37502e3749 100644
--- a/app/assets/javascripts/discourse/mixins/grant-badge-controller.js.es6
+++ b/app/assets/javascripts/discourse/mixins/grant-badge-controller.js.es6
@@ -1,8 +1,10 @@
+import { empty } from "@ember/object/computed";
import computed from "ember-addons/ember-computed-decorators";
import UserBadge from "discourse/models/user-badge";
import { convertIconClass } from "discourse-common/lib/icon-library";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
@computed("allBadges.[]", "userBadges.[]")
grantableBadges(allBadges, userBadges) {
const granted = userBadges.reduce((map, badge) => {
@@ -27,7 +29,7 @@ export default Ember.Mixin.create({
.sort((a, b) => a.get("name").localeCompare(b.get("name")));
},
- noGrantableBadges: Ember.computed.empty("grantableBadges"),
+ noGrantableBadges: empty("grantableBadges"),
@computed("selectedBadgeId", "grantableBadges")
selectedBadgeGrantable(selectedBadgeId, grantableBadges) {
diff --git a/app/assets/javascripts/discourse/mixins/load-more.js.es6 b/app/assets/javascripts/discourse/mixins/load-more.js.es6
index caf86100ea..a7761e1399 100644
--- a/app/assets/javascripts/discourse/mixins/load-more.js.es6
+++ b/app/assets/javascripts/discourse/mixins/load-more.js.es6
@@ -1,9 +1,10 @@
import Eyeline from "discourse/lib/eyeline";
import Scrolling from "discourse/mixins/scrolling";
import { on } from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
// Provides the ability to load more items for a view which is scrolled to the bottom.
-export default Ember.Mixin.create(Scrolling, {
+export default Mixin.create(Scrolling, {
scrolled() {
const eyeline = this.eyeline;
return eyeline && eyeline.update();
diff --git a/app/assets/javascripts/discourse/mixins/mobile-scroll-direction.js.es6 b/app/assets/javascripts/discourse/mixins/mobile-scroll-direction.js.es6
index 0f27500a09..b2eabe0815 100644
--- a/app/assets/javascripts/discourse/mixins/mobile-scroll-direction.js.es6
+++ b/app/assets/javascripts/discourse/mixins/mobile-scroll-direction.js.es6
@@ -1,7 +1,9 @@
+import { debounce } from "@ember/runloop";
+import Mixin from "@ember/object/mixin";
// Small buffer so that very tiny scrolls don't trigger mobile header switch
const MOBILE_SCROLL_TOLERANCE = 5;
-export default Ember.Mixin.create({
+export default Mixin.create({
_lastScroll: null,
_bottomHit: 0,
@@ -42,7 +44,7 @@ export default Ember.Mixin.create({
// If the user reaches the very bottom of the topic, we only want to reset
// this scroll direction after a second scrolldown. This is a nicer event
// similar to what Safari and Chrome do.
- Ember.run.debounce(() => {
+ debounce(() => {
this._bottomHit = 1;
}, 1000);
diff --git a/app/assets/javascripts/discourse/mixins/modal-functionality.js.es6 b/app/assets/javascripts/discourse/mixins/modal-functionality.js.es6
index cb4ba7717f..70b5bd010c 100644
--- a/app/assets/javascripts/discourse/mixins/modal-functionality.js.es6
+++ b/app/assets/javascripts/discourse/mixins/modal-functionality.js.es6
@@ -1,6 +1,7 @@
import showModal from "discourse/lib/show-modal";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
flash(text, messageClass) {
this.appEvents.trigger("modal-body:flash", { text, messageClass });
},
diff --git a/app/assets/javascripts/discourse/mixins/name-validation.js.es6 b/app/assets/javascripts/discourse/mixins/name-validation.js.es6
index 5b505c1359..46f1b4dfae 100644
--- a/app/assets/javascripts/discourse/mixins/name-validation.js.es6
+++ b/app/assets/javascripts/discourse/mixins/name-validation.js.es6
@@ -1,7 +1,9 @@
+import { isEmpty } from "@ember/utils";
import InputValidation from "discourse/models/input-validation";
import { default as computed } from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
@computed()
nameInstructions() {
return I18n.t(
@@ -14,10 +16,7 @@ export default Ember.Mixin.create({
// Validate the name.
@computed("accountName")
nameValidation() {
- if (
- this.siteSettings.full_name_required &&
- Ember.isEmpty(this.accountName)
- ) {
+ if (this.siteSettings.full_name_required && isEmpty(this.accountName)) {
return InputValidation.create({ failed: true });
}
diff --git a/app/assets/javascripts/discourse/mixins/open-composer.js.es6 b/app/assets/javascripts/discourse/mixins/open-composer.js.es6
index 7d925ab652..5896a09d5d 100644
--- a/app/assets/javascripts/discourse/mixins/open-composer.js.es6
+++ b/app/assets/javascripts/discourse/mixins/open-composer.js.es6
@@ -1,7 +1,8 @@
// This mixin allows a route to open the composer
import Composer from "discourse/models/composer";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
openComposer(controller) {
let categoryId = controller.get("category.id");
if (
@@ -15,7 +16,7 @@ export default Ember.Mixin.create({
this.controllerFor("composer").open({
categoryId,
action: Composer.CREATE_TOPIC,
- draftKey: controller.get("model.draft_key") || Composer.CREATE_TOPIC,
+ draftKey: controller.get("model.draft_key") || Composer.NEW_TOPIC_KEY,
draftSequence: controller.get("model.draft_sequence") || 0
});
},
diff --git a/app/assets/javascripts/discourse/mixins/pan-events.js.es6 b/app/assets/javascripts/discourse/mixins/pan-events.js.es6
index 1608d72fea..fb05901205 100644
--- a/app/assets/javascripts/discourse/mixins/pan-events.js.es6
+++ b/app/assets/javascripts/discourse/mixins/pan-events.js.es6
@@ -1,3 +1,4 @@
+import Mixin from "@ember/object/mixin";
/**
Pan events is a mixin that allows components to detect and respond to swipe gestures
It fires callbacks for panStart, panEnd, panMove with the pan state, and the original event.
@@ -6,7 +7,7 @@ export const SWIPE_VELOCITY = 40;
export const SWIPE_DISTANCE_THRESHOLD = 50;
export const SWIPE_VELOCITY_THRESHOLD = 0.12;
export const MINIMUM_SWIPE_DISTANCE = 5;
-export default Ember.Mixin.create({
+export default Mixin.create({
//velocity is pixels per ms
_panState: null,
diff --git a/app/assets/javascripts/discourse/mixins/password-validation.js.es6 b/app/assets/javascripts/discourse/mixins/password-validation.js.es6
index 50a98e8790..3ddf9131f0 100644
--- a/app/assets/javascripts/discourse/mixins/password-validation.js.es6
+++ b/app/assets/javascripts/discourse/mixins/password-validation.js.es6
@@ -1,7 +1,9 @@
+import { isEmpty } from "@ember/utils";
import InputValidation from "discourse/models/input-validation";
import { default as computed } from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
rejectedPasswords: null,
init() {
@@ -54,7 +56,7 @@ export default Ember.Mixin.create({
}
// If blank, fail without a reason
- if (Ember.isEmpty(password)) {
+ if (isEmpty(password)) {
return InputValidation.create({ failed: true });
}
@@ -66,14 +68,14 @@ export default Ember.Mixin.create({
});
}
- if (!Ember.isEmpty(accountUsername) && password === accountUsername) {
+ if (!isEmpty(accountUsername) && password === accountUsername) {
return InputValidation.create({
failed: true,
reason: I18n.t("user.password.same_as_username")
});
}
- if (!Ember.isEmpty(accountEmail) && password === accountEmail) {
+ if (!isEmpty(accountEmail) && password === accountEmail) {
return InputValidation.create({
failed: true,
reason: I18n.t("user.password.same_as_email")
diff --git a/app/assets/javascripts/discourse/mixins/preferences-tab-controller.js.es6 b/app/assets/javascripts/discourse/mixins/preferences-tab-controller.js.es6
index 080c81fe9f..7e49326f41 100644
--- a/app/assets/javascripts/discourse/mixins/preferences-tab-controller.js.es6
+++ b/app/assets/javascripts/discourse/mixins/preferences-tab-controller.js.es6
@@ -1,6 +1,7 @@
import { default as computed } from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
saved: false,
@computed("model.isSaving")
diff --git a/app/assets/javascripts/discourse/mixins/scroll-top.js.es6 b/app/assets/javascripts/discourse/mixins/scroll-top.js.es6
index 630227b8fa..82ae1c0479 100644
--- a/app/assets/javascripts/discourse/mixins/scroll-top.js.es6
+++ b/app/assets/javascripts/discourse/mixins/scroll-top.js.es6
@@ -1,5 +1,7 @@
+import { scheduleOnce } from "@ember/runloop";
import DiscourseURL from "discourse/lib/url";
import { deprecated } from "discourse/mixins/scroll-top";
+import Mixin from "@ember/object/mixin";
const context = {
_scrollTop() {
@@ -14,10 +16,10 @@ function scrollTop() {
if (DiscourseURL.isJumpScheduled()) {
return;
}
- Ember.run.scheduleOnce("afterRender", context, context._scrollTop);
+ scheduleOnce("afterRender", context, context._scrollTop);
}
-export default Ember.Mixin.create({
+export default Mixin.create({
didInsertElement() {
deprecated(
"The `ScrollTop` mixin is deprecated. Replace it with a `{{d-section}}` component"
diff --git a/app/assets/javascripts/discourse/mixins/scrolling.js.es6 b/app/assets/javascripts/discourse/mixins/scrolling.js.es6
index 690bf1168f..b690c77de4 100644
--- a/app/assets/javascripts/discourse/mixins/scrolling.js.es6
+++ b/app/assets/javascripts/discourse/mixins/scrolling.js.es6
@@ -1,4 +1,6 @@
+import { scheduleOnce } from "@ember/runloop";
import debounce from "discourse/lib/debounce";
+import Mixin from "@ember/object/mixin";
/**
This object provides the DOM methods we need for our Mixin to bind to scrolling
@@ -23,7 +25,7 @@ const ScrollingDOMMethods = {
}
};
-const Scrolling = Ember.Mixin.create({
+const Scrolling = Mixin.create({
// Begin watching for scroll events. By default they will be called at max every 100ms.
// call with {debounce: N} for a diff time
bindScrolling(opts) {
@@ -37,7 +39,7 @@ const Scrolling = Ember.Mixin.create({
if (router.activeTransition) {
return;
}
- return Ember.run.scheduleOnce("afterRender", this, "scrolled");
+ return scheduleOnce("afterRender", this, "scrolled");
};
if (opts.debounce) {
diff --git a/app/assets/javascripts/discourse/mixins/singleton.js.es6 b/app/assets/javascripts/discourse/mixins/singleton.js.es6
index 62a8265613..5c4ac8238d 100644
--- a/app/assets/javascripts/discourse/mixins/singleton.js.es6
+++ b/app/assets/javascripts/discourse/mixins/singleton.js.es6
@@ -8,7 +8,7 @@
```javascript
// Define your class and apply the Mixin
- User = Ember.Object.extend({});
+ User = EmberObject.extend({});
User.reopenClass(Singleton);
// Retrieve the current instance:
@@ -34,7 +34,7 @@
```javascript
// Define your class and apply the Mixin
- Foot = Ember.Object.extend({});
+ Foot = EmberObject.extend({});
Foot.reopenClass(Singleton, {
createCurrent: function() {
return Foot.create({toes: 5});
@@ -45,7 +45,9 @@
```
**/
-const Singleton = Ember.Mixin.create({
+import Mixin from "@ember/object/mixin";
+
+const Singleton = Mixin.create({
current() {
if (!this._current) {
this._current = this.createCurrent();
diff --git a/app/assets/javascripts/discourse/mixins/upload.js.es6 b/app/assets/javascripts/discourse/mixins/upload.js.es6
index d3f83ff419..a3b0d8626a 100644
--- a/app/assets/javascripts/discourse/mixins/upload.js.es6
+++ b/app/assets/javascripts/discourse/mixins/upload.js.es6
@@ -2,9 +2,12 @@ import {
displayErrorForUpload,
validateUploadedFiles
} from "discourse/lib/utilities";
-import getUrl from "discourse-common/lib/get-url";
-export default Ember.Mixin.create({
+import getUrl from "discourse-common/lib/get-url";
+import { on } from "@ember/object/evented";
+import Mixin from "@ember/object/mixin";
+
+export default Mixin.create({
uploading: false,
uploadProgress: 0,
@@ -33,7 +36,7 @@ export default Ember.Mixin.create({
return {};
},
- _initialize: function() {
+ _initialize: on("didInsertElement", function() {
const $upload = $(this.element);
const reset = () =>
this.setProperties({ uploading: false, uploadProgress: 0 });
@@ -101,9 +104,9 @@ export default Ember.Mixin.create({
}
reset();
});
- }.on("didInsertElement"),
+ }),
- _destroy: function() {
+ _destroy: on("willDestroyElement", function() {
this.messageBus && this.messageBus.unsubscribe("/uploads/" + this.type);
const $upload = $(this.element);
@@ -113,5 +116,5 @@ export default Ember.Mixin.create({
/* wasn't initialized yet */
}
$upload.off();
- }.on("willDestroyElement")
+ })
});
diff --git a/app/assets/javascripts/discourse/mixins/user-fields-validation.js.es6 b/app/assets/javascripts/discourse/mixins/user-fields-validation.js.es6
index 57a4b9cec0..ec007c993d 100644
--- a/app/assets/javascripts/discourse/mixins/user-fields-validation.js.es6
+++ b/app/assets/javascripts/discourse/mixins/user-fields-validation.js.es6
@@ -1,10 +1,13 @@
+import { isEmpty } from "@ember/utils";
+import EmberObject from "@ember/object";
import InputValidation from "discourse/models/input-validation";
import {
on,
default as computed
} from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
@on("init")
_createUserFields() {
if (!this.site) {
@@ -14,7 +17,7 @@ export default Ember.Mixin.create({
let userFields = this.site.get("user_fields");
if (userFields) {
userFields = _.sortBy(userFields, "position").map(function(f) {
- return Ember.Object.create({ value: null, field: f });
+ return EmberObject.create({ value: null, field: f });
});
}
this.set("userFields", userFields);
@@ -27,10 +30,10 @@ export default Ember.Mixin.create({
if (userFields) {
userFields = userFields.filterBy("field.required");
}
- if (!Ember.isEmpty(userFields)) {
+ if (!isEmpty(userFields)) {
const anyEmpty = userFields.any(uf => {
const val = uf.get("value");
- return !val || Ember.isEmpty(val);
+ return !val || isEmpty(val);
});
if (anyEmpty) {
return InputValidation.create({ failed: true });
diff --git a/app/assets/javascripts/discourse/mixins/username-validation.js.es6 b/app/assets/javascripts/discourse/mixins/username-validation.js.es6
index 892f587b85..66e86221a9 100644
--- a/app/assets/javascripts/discourse/mixins/username-validation.js.es6
+++ b/app/assets/javascripts/discourse/mixins/username-validation.js.es6
@@ -1,9 +1,11 @@
+import { isEmpty } from "@ember/utils";
import InputValidation from "discourse/models/input-validation";
import debounce from "discourse/lib/debounce";
import { setting } from "discourse/lib/computed";
import { default as computed } from "ember-addons/ember-computed-decorators";
+import Mixin from "@ember/object/mixin";
-export default Ember.Mixin.create({
+export default Mixin.create({
uniqueUsernameValidation: null,
maxUsernameLength: setting("max_username_length"),
@@ -14,7 +16,7 @@ export default Ember.Mixin.create({
Discourse.User.checkUsername(null, this.accountEmail).then(result => {
if (
result.suggestion &&
- (Ember.isEmpty(this.accountUsername) ||
+ (isEmpty(this.accountUsername) ||
this.accountUsername === this.get("authOptions.username"))
) {
this.setProperties({
@@ -37,7 +39,7 @@ export default Ember.Mixin.create({
}
// If blank, fail without a reason
- if (Ember.isEmpty(accountUsername)) {
+ if (isEmpty(accountUsername)) {
return InputValidation.create({ failed: true });
}
@@ -67,7 +69,7 @@ export default Ember.Mixin.create({
shouldCheckUsernameAvailability() {
return (
- !Ember.isEmpty(this.accountUsername) &&
+ !isEmpty(this.accountUsername) &&
this.accountUsername.length >= this.minUsernameLength
);
},
diff --git a/app/assets/javascripts/discourse/models/action-summary.js.es6 b/app/assets/javascripts/discourse/models/action-summary.js.es6
index 283a76981d..ce8259b9c0 100644
--- a/app/assets/javascripts/discourse/models/action-summary.js.es6
+++ b/app/assets/javascripts/discourse/models/action-summary.js.es6
@@ -1,9 +1,10 @@
+import { or } from "@ember/object/computed";
import { ajax } from "discourse/lib/ajax";
import RestModel from "discourse/models/rest";
import { popupAjaxError } from "discourse/lib/ajax-error";
export default RestModel.extend({
- canToggle: Ember.computed.or("can_undo", "can_act"),
+ canToggle: or("can_undo", "can_act"),
// Remove it
removeAction: function() {
diff --git a/app/assets/javascripts/discourse/models/archetype.js.es6 b/app/assets/javascripts/discourse/models/archetype.js.es6
index 9ba6e6744b..912a45b45c 100644
--- a/app/assets/javascripts/discourse/models/archetype.js.es6
+++ b/app/assets/javascripts/discourse/models/archetype.js.es6
@@ -1,8 +1,9 @@
+import { gt, not } from "@ember/object/computed";
import { propertyEqual } from "discourse/lib/computed";
import RestModel from "discourse/models/rest";
export default RestModel.extend({
- hasOptions: Ember.computed.gt("options.length", 0),
+ hasOptions: gt("options.length", 0),
isDefault: propertyEqual("id", "site.default_archetype"),
- notDefault: Ember.computed.not("isDefault")
+ notDefault: not("isDefault")
});
diff --git a/app/assets/javascripts/discourse/models/badge.js.es6 b/app/assets/javascripts/discourse/models/badge.js.es6
index d70a5fbbe6..88203b5084 100644
--- a/app/assets/javascripts/discourse/models/badge.js.es6
+++ b/app/assets/javascripts/discourse/models/badge.js.es6
@@ -1,10 +1,13 @@
+import { none } from "@ember/object/computed";
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import BadgeGrouping from "discourse/models/badge-grouping";
import RestModel from "discourse/models/rest";
import computed from "ember-addons/ember-computed-decorators";
+import { Promise } from "rsvp";
const Badge = RestModel.extend({
- newBadge: Ember.computed.none("id"),
+ newBadge: none("id"),
@computed
url() {
@@ -51,7 +54,7 @@ const Badge = RestModel.extend({
},
destroy() {
- if (this.newBadge) return Ember.RSVP.resolve();
+ if (this.newBadge) return Promise.resolve();
return ajax(`/admin/badges/${this.id}`, {
type: "DELETE"
@@ -66,7 +69,7 @@ Badge.reopenClass({
if ("badge_types" in json) {
json.badge_types.forEach(
badgeTypeJson =>
- (badgeTypes[badgeTypeJson.id] = Ember.Object.create(badgeTypeJson))
+ (badgeTypes[badgeTypeJson.id] = EmberObject.create(badgeTypeJson))
);
}
diff --git a/app/assets/javascripts/discourse/models/category.js.es6 b/app/assets/javascripts/discourse/models/category.js.es6
index 5b663c48a0..4248f6a8f8 100644
--- a/app/assets/javascripts/discourse/models/category.js.es6
+++ b/app/assets/javascripts/discourse/models/category.js.es6
@@ -1,10 +1,14 @@
+import { get } from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import RestModel from "discourse/models/rest";
import computed from "ember-addons/ember-computed-decorators";
import { on } from "ember-addons/ember-computed-decorators";
import PermissionType from "discourse/models/permission-type";
+import { NotificationLevels } from "discourse/lib/notification-levels";
const Category = RestModel.extend({
+ permissions: null,
+
@on("init")
setupGroupsAndPermissions() {
const availableGroups = this.available_groups;
@@ -28,6 +32,13 @@ const Category = RestModel.extend({
}
},
+ @on("init")
+ setupRequiredTagGroups() {
+ if (this.required_tag_group_name) {
+ this.set("required_tag_groups", [this.required_tag_group_name]);
+ }
+ },
+
@computed
availablePermissions() {
return [
@@ -42,6 +53,11 @@ const Category = RestModel.extend({
return { type: "category", id, category: this };
},
+ @computed("notification_level")
+ isMuted(notificationLevel) {
+ return notificationLevel === NotificationLevels.MUTED;
+ },
+
@computed("name")
url() {
return Discourse.getURL("/c/") + Category.slugFor(this);
@@ -119,6 +135,10 @@ const Category = RestModel.extend({
allowed_tags: this.allowed_tags,
allowed_tag_groups: this.allowed_tag_groups,
allow_global_tags: this.allow_global_tags,
+ required_tag_group_name: this.required_tag_groups
+ ? this.required_tag_groups[0]
+ : null,
+ min_tags_from_required_group: this.min_tags_from_required_group,
sort_order: this.sort_order,
sort_ascending: this.sort_ascending,
topic_featured_link_allowed: this.topic_featured_link_allowed,
@@ -161,15 +181,6 @@ const Category = RestModel.extend({
this.availableGroups.addObject(permission.group_name);
},
- @computed
- permissions() {
- return Ember.A([
- { group_name: "everyone", permission: PermissionType.create({ id: 1 }) },
- { group_name: "admins", permission: PermissionType.create({ id: 2 }) },
- { group_name: "crap", permission: PermissionType.create({ id: 3 }) }
- ]);
- },
-
@computed("topics")
latestTopic(topics) {
if (topics && topics.length) {
@@ -222,15 +233,15 @@ Category.reopenClass({
slugFor(category, separator = "/") {
if (!category) return "";
- const parentCategory = Ember.get(category, "parentCategory");
+ const parentCategory = get(category, "parentCategory");
let result = "";
if (parentCategory) {
result = Category.slugFor(parentCategory) + separator;
}
- const id = Ember.get(category, "id"),
- slug = Ember.get(category, "slug");
+ const id = get(category, "id"),
+ slug = get(category, "slug");
return !slug || slug.trim().length === 0
? `${result}${id}-category`
@@ -250,7 +261,11 @@ Category.reopenClass({
},
findSingleBySlug(slug) {
- return Category.list().find(c => Category.slugFor(c) === slug);
+ if (Discourse.SiteSettings.slug_generation_method !== "encoded") {
+ return Category.list().find(c => Category.slugFor(c) === slug);
+ } else {
+ return Category.list().find(c => Category.slugFor(c) === encodeURI(slug));
+ }
},
findById(id) {
@@ -286,7 +301,11 @@ Category.reopenClass({
return (
item &&
item.get("parentCategory") === parentCategory &&
- Category.slugFor(item) === parentSlug + "/" + slug
+ ((Discourse.SiteSettings.slug_generation_method !== "encoded" &&
+ Category.slugFor(item) === parentSlug + "/" + slug) ||
+ (Discourse.SiteSettings.slug_generation_method === "encoded" &&
+ Category.slugFor(item) ===
+ encodeURI(parentSlug) + "/" + encodeURI(slug)))
);
});
}
diff --git a/app/assets/javascripts/discourse/models/composer.js.es6 b/app/assets/javascripts/discourse/models/composer.js.es6
index de9d9042bc..8e3a1af259 100644
--- a/app/assets/javascripts/discourse/models/composer.js.es6
+++ b/app/assets/javascripts/discourse/models/composer.js.es6
@@ -1,3 +1,9 @@
+import { isEmpty } from "@ember/utils";
+import { reads, equal, not, or, and } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { next } from "@ember/runloop";
+import { cancel } from "@ember/runloop";
+import { later } from "@ember/runloop";
import RestModel from "discourse/models/rest";
import Topic from "discourse/models/topic";
import { throwAjaxError } from "discourse/lib/ajax-error";
@@ -11,18 +17,18 @@ import {
import { escapeExpression, tinyAvatar } from "discourse/lib/utilities";
import { propertyNotEqual } from "discourse/lib/computed";
import throttle from "discourse/lib/throttle";
+import { Promise } from "rsvp";
+import { set } from "@ember/object";
// The actions the composer can take
export const CREATE_TOPIC = "createTopic",
CREATE_SHARED_DRAFT = "createSharedDraft",
EDIT_SHARED_DRAFT = "editSharedDraft",
PRIVATE_MESSAGE = "privateMessage",
- NEW_PRIVATE_MESSAGE_KEY = "new_private_message",
- NEW_TOPIC_KEY = "new_topic",
REPLY = "reply",
EDIT = "edit",
- REPLY_AS_NEW_TOPIC_KEY = "reply_as_new_topic",
- REPLY_AS_NEW_PRIVATE_MESSAGE_KEY = "reply_as_new_private_message";
+ NEW_PRIVATE_MESSAGE_KEY = "new_private_message",
+ NEW_TOPIC_KEY = "new_topic";
function isEdit(action) {
return action === EDIT || action === EDIT_SHARED_DRAFT;
@@ -57,6 +63,20 @@ const CLOSED = "closed",
tags: "topic.tags",
featuredLink: "topic.featured_link"
},
+ _draft_serializer = {
+ reply: "reply",
+ action: "action",
+ title: "title",
+ categoryId: "categoryId",
+ archetypeId: "archetypeId",
+ whisper: "whisper",
+ metaData: "metaData",
+ composerTime: "composerTime",
+ typingTime: "typingTime",
+ postId: "post.id",
+ usernames: "targetUsernames"
+ },
+ _add_draft_fields = {},
FAST_REPLY_LENGTH_THRESHOLD = 10000;
export const SAVE_LABELS = {
@@ -84,9 +104,9 @@ const Composer = RestModel.extend({
draftSaving: false,
draftSaved: false,
- archetypes: Ember.computed.reads("site.archetypes"),
+ archetypes: reads("site.archetypes"),
- sharedDraft: Ember.computed.equal("action", CREATE_SHARED_DRAFT),
+ sharedDraft: equal("action", CREATE_SHARED_DRAFT),
@computed
categoryId: {
@@ -99,7 +119,7 @@ const Composer = RestModel.extend({
set(categoryId) {
const oldCategoryId = this._categoryId;
- if (Ember.isEmpty(categoryId)) {
+ if (isEmpty(categoryId)) {
categoryId = null;
}
this._categoryId = categoryId;
@@ -124,11 +144,16 @@ const Composer = RestModel.extend({
: null;
},
- creatingTopic: Ember.computed.equal("action", CREATE_TOPIC),
- creatingSharedDraft: Ember.computed.equal("action", CREATE_SHARED_DRAFT),
- creatingPrivateMessage: Ember.computed.equal("action", PRIVATE_MESSAGE),
- notCreatingPrivateMessage: Ember.computed.not("creatingPrivateMessage"),
- notPrivateMessage: Ember.computed.not("privateMessage"),
+ creatingTopic: equal("action", CREATE_TOPIC),
+ creatingSharedDraft: equal("action", CREATE_SHARED_DRAFT),
+ creatingPrivateMessage: equal("action", PRIVATE_MESSAGE),
+ notCreatingPrivateMessage: not("creatingPrivateMessage"),
+ notPrivateMessage: not("privateMessage"),
+
+ @computed("editingPost", "topic.details.can_edit")
+ disableTitleInput(editingPost, canEditTopic) {
+ return editingPost && !canEditTopic;
+ },
@computed("privateMessage", "archetype.hasOptions")
showCategoryChooser(isPrivateMessage, hasOptions) {
@@ -143,17 +168,17 @@ const Composer = RestModel.extend({
);
},
- topicFirstPost: Ember.computed.or("creatingTopic", "editingFirstPost"),
+ topicFirstPost: or("creatingTopic", "editingFirstPost"),
@computed("action")
editingPost: isEdit,
- replyingToTopic: Ember.computed.equal("action", REPLY),
+ replyingToTopic: equal("action", REPLY),
- viewOpen: Ember.computed.equal("composeState", OPEN),
- viewDraft: Ember.computed.equal("composeState", DRAFT),
- viewFullscreen: Ember.computed.equal("composeState", FULLSCREEN),
- viewOpenOrFullscreen: Ember.computed.or("viewOpen", "viewFullscreen"),
+ viewOpen: equal("composeState", OPEN),
+ viewDraft: equal("composeState", DRAFT),
+ viewFullscreen: equal("composeState", FULLSCREEN),
+ viewOpenOrFullscreen: or("viewOpen", "viewFullscreen"),
@observes("composeState")
composeStateChanged() {
@@ -198,7 +223,7 @@ const Composer = RestModel.extend({
@observes("archetype")
archetypeChanged() {
- return this.set("metaData", Ember.Object.create());
+ return this.set("metaData", EmberObject.create());
},
// view detected user is typing
@@ -211,16 +236,16 @@ const Composer = RestModel.extend({
false
),
- editingFirstPost: Ember.computed.and("editingPost", "post.firstPost"),
+ editingFirstPost: and("editingPost", "post.firstPost"),
- canEditTitle: Ember.computed.or(
+ canEditTitle: or(
"creatingTopic",
"creatingPrivateMessage",
"editingFirstPost",
"creatingSharedDraft"
),
- canCategorize: Ember.computed.and(
+ canCategorize: and(
"canEditTitle",
"notCreatingPrivateMessage",
"notPrivateMessage"
@@ -398,7 +423,7 @@ const Composer = RestModel.extend({
@computed("metaData")
hasMetaData(metaData) {
- return metaData ? Ember.isEmpty(Ember.keys(metaData)) : false;
+ return metaData ? isEmpty(Ember.keys(metaData)) : false;
},
replyDirty: propertyNotEqual("reply", "originalText"),
@@ -588,7 +613,7 @@ const Composer = RestModel.extend({
}
}
- if (!Ember.isEmpty(reply)) {
+ if (!isEmpty(reply)) {
return;
}
@@ -611,7 +636,7 @@ const Composer = RestModel.extend({
if (!opts) opts = {};
this.set("loading", false);
- const replyBlank = Ember.isEmpty(this.reply);
+ const replyBlank = isEmpty(this.reply);
const composer = this;
if (
@@ -660,7 +685,7 @@ const Composer = RestModel.extend({
this.setProperties({
archetypeId: opts.archetypeId || this.site.default_archetype,
- metaData: opts.metaData ? Ember.Object.create(opts.metaData) : null,
+ metaData: opts.metaData ? EmberObject.create(opts.metaData) : null,
reply: opts.reply || this.reply || ""
});
@@ -722,18 +747,30 @@ const Composer = RestModel.extend({
composer.appEvents.trigger("composer:reply-reloaded", composer);
}
+ // Ensure additional draft fields are set
+ Object.keys(_add_draft_fields).forEach(f => {
+ this.set(_add_draft_fields[f], opts[f]);
+ });
+
return false;
},
- save(opts) {
- if (!this.cantSubmitPost) {
- // change category may result in some effect for topic featured link
- if (!this.canEditTopicFeaturedLink) {
- this.set("featuredLink", null);
- }
+ // Overwrite to implement custom logic
+ beforeSave() {
+ return Promise.resolve();
+ },
- return this.editingPost ? this.editPost(opts) : this.createPost(opts);
- }
+ save(opts) {
+ return this.beforeSave().then(() => {
+ if (!this.cantSubmitPost) {
+ // change category may result in some effect for topic featured link
+ if (!this.canEditTopicFeaturedLink) {
+ this.set("featuredLink", null);
+ }
+
+ return this.editingPost ? this.editPost(opts) : this.createPost(opts);
+ }
+ });
},
clearState() {
@@ -757,34 +794,34 @@ const Composer = RestModel.extend({
editPost(opts) {
const post = this.post;
const oldCooked = post.cooked;
- let promise = Ember.RSVP.resolve();
+ let promise = Promise.resolve();
// Update the topic if we're editing the first post
- if (
- this.title &&
- post.post_number === 1 &&
- this.get("topic.details.can_edit")
- ) {
- const topicProps = this.getProperties(
- Object.keys(_edit_topic_serializer)
- );
- // frontend should have featuredLink but backend needs featured_link
- if (topicProps.featuredLink) {
- topicProps.featured_link = topicProps.featuredLink;
- delete topicProps.featuredLink;
- }
-
+ if (this.title && post.post_number === 1) {
const topic = this.topic;
- // If we're editing a shared draft, keep the original category
- if (this.action === EDIT_SHARED_DRAFT) {
- const destinationCategoryId = topicProps.categoryId;
- promise = promise.then(() =>
- topic.updateDestinationCategory(destinationCategoryId)
+ if (topic.details.can_edit) {
+ const topicProps = this.getProperties(
+ Object.keys(_edit_topic_serializer)
);
- topicProps.categoryId = topic.get("category.id");
+ // frontend should have featuredLink but backend needs featured_link
+ if (topicProps.featuredLink) {
+ topicProps.featured_link = topicProps.featuredLink;
+ delete topicProps.featuredLink;
+ }
+
+ // If we're editing a shared draft, keep the original category
+ if (this.action === EDIT_SHARED_DRAFT) {
+ const destinationCategoryId = topicProps.categoryId;
+ promise = promise.then(() =>
+ topic.updateDestinationCategory(destinationCategoryId)
+ );
+ topicProps.categoryId = topic.get("category.id");
+ }
+ promise = promise.then(() => Topic.update(topic, topicProps));
+ } else if (topic.details.can_edit_tags) {
+ promise = promise.then(() => topic.updateTags(this.tags));
}
- promise = promise.then(() => Topic.update(topic, topicProps));
}
const props = {
@@ -823,7 +860,7 @@ const Composer = RestModel.extend({
Object.keys(serializer).forEach(f => {
const val = this.get(serializer[f]);
if (typeof val !== "undefined") {
- Ember.set(dest, f, val);
+ set(dest, f, val);
}
});
return dest;
@@ -964,7 +1001,7 @@ const Composer = RestModel.extend({
post.set("reply_count", post.reply_count - 1);
}
}
- Ember.run.next(() => composer.set("composeState", OPEN));
+ next(() => composer.set("composeState", OPEN));
})
);
},
@@ -1015,35 +1052,26 @@ const Composer = RestModel.extend({
});
if (this._clearingStatus) {
- Ember.run.cancel(this._clearingStatus);
+ cancel(this._clearingStatus);
this._clearingStatus = null;
}
- let data = this.getProperties(
- "reply",
- "action",
- "title",
- "categoryId",
- "archetypeId",
- "whisper",
- "metaData",
- "composerTime",
- "typingTime",
- "tags",
- "noBump"
- );
+ let data = this.serialize(_draft_serializer);
- data = Object.assign(data, {
- usernames: this.targetUsernames,
- postId: this.get("post.id")
- });
-
- if (data.postId && !Ember.isEmpty(this.originalText)) {
+ if (data.postId && !isEmpty(this.originalText)) {
data.originalText = this.originalText;
}
- return Draft.save(this.draftKey, this.draftSequence, data)
+ return Draft.save(
+ this.draftKey,
+ this.draftSequence,
+ data,
+ this.messageBus.clientId
+ )
.then(result => {
+ if (result.draft_sequence) {
+ this.draftSequence = result.draft_sequence;
+ }
if (result.conflict_user) {
this.setProperties({
draftSaving: false,
@@ -1058,10 +1086,27 @@ const Composer = RestModel.extend({
});
}
})
- .catch(() => {
+ .catch(e => {
+ let draftStatus;
+ const xhr = e && e.jqXHR;
+
+ if (
+ xhr &&
+ xhr.status === 409 &&
+ xhr.responseJSON &&
+ xhr.responseJSON.errors &&
+ xhr.responseJSON.errors.length
+ ) {
+ const json = e.jqXHR.responseJSON;
+ draftStatus = json.errors[0];
+ if (json.extras && json.extras.description) {
+ bootbox.alert(json.extras.description);
+ }
+ }
+
this.setProperties({
draftSaving: false,
- draftStatus: I18n.t("composer.drafts_offline"),
+ draftStatus: draftStatus || I18n.t("composer.drafts_offline"),
draftConflictUser: null
});
});
@@ -1072,7 +1117,7 @@ const Composer = RestModel.extend({
const draftStatus = this.draftStatus;
if (draftStatus && !this._clearingStatus) {
- this._clearingStatus = Ember.run.later(
+ this._clearingStatus = later(
this,
() => {
this.setProperties({ draftStatus: null, draftConflictUser: null });
@@ -1113,6 +1158,18 @@ Composer.reopenClass({
return Object.keys(_create_serializer);
},
+ serializeToDraft(fieldName, property) {
+ if (!property) {
+ property = fieldName;
+ }
+ _draft_serializer[fieldName] = property;
+ _add_draft_fields[fieldName] = property;
+ },
+
+ serializedFieldsForDraft() {
+ return Object.keys(_draft_serializer);
+ },
+
// The status the compose view can have
CLOSED,
SAVING,
@@ -1130,8 +1187,7 @@ Composer.reopenClass({
// Draft key
NEW_PRIVATE_MESSAGE_KEY,
- REPLY_AS_NEW_TOPIC_KEY,
- REPLY_AS_NEW_PRIVATE_MESSAGE_KEY
+ NEW_TOPIC_KEY
});
export default Composer;
diff --git a/app/assets/javascripts/discourse/models/draft.js.es6 b/app/assets/javascripts/discourse/models/draft.js.es6
index abba8511f5..62fefef8c7 100644
--- a/app/assets/javascripts/discourse/models/draft.js.es6
+++ b/app/assets/javascripts/discourse/models/draft.js.es6
@@ -21,11 +21,11 @@ Draft.reopenClass({
return current;
},
- save(key, sequence, data) {
+ save(key, sequence, data, clientId) {
data = typeof data === "string" ? data : JSON.stringify(data);
return ajax("/draft.json", {
type: "POST",
- data: { draft_key: key, sequence, data }
+ data: { draft_key: key, sequence, data, owner: clientId }
});
}
});
diff --git a/app/assets/javascripts/discourse/models/group.js.es6 b/app/assets/javascripts/discourse/models/group.js.es6
index 2b0081e4e0..b25746471e 100644
--- a/app/assets/javascripts/discourse/models/group.js.es6
+++ b/app/assets/javascripts/discourse/models/group.js.es6
@@ -1,3 +1,5 @@
+import { isEmpty } from "@ember/utils";
+import { notEmpty, equal } from "@ember/object/computed";
import { ajax } from "discourse/lib/ajax";
import {
default as computed,
@@ -9,6 +11,7 @@ import Category from "discourse/models/category";
import User from "discourse/models/user";
import Topic from "discourse/models/topic";
import { popupAjaxError } from "discourse/lib/ajax-error";
+import EmberObject from "@ember/object";
const Group = RestModel.extend({
limit: 50,
@@ -21,11 +24,11 @@ const Group = RestModel.extend({
this.set("owners", []);
},
- hasOwners: Ember.computed.notEmpty("owners"),
+ hasOwners: notEmpty("owners"),
@computed("automatic_membership_email_domains")
emailDomains(value) {
- return Ember.isEmpty(value) ? "" : value;
+ return isEmpty(value) ? "" : value;
},
@computed("automatic")
@@ -42,7 +45,7 @@ const Group = RestModel.extend({
},
findMembers(params) {
- if (Ember.isEmpty(this.name)) {
+ if (isEmpty(this.name) || !this.can_see_members) {
return;
}
@@ -135,7 +138,7 @@ const Group = RestModel.extend({
: null;
},
- canEveryoneMention: Ember.computed.equal("mentionable_level", 99),
+ canEveryoneMention: equal("mentionable_level", 99),
@computed("visibility_level")
isPrivate(visibilityLevel) {
@@ -216,7 +219,7 @@ const Group = RestModel.extend({
return ajax(`/groups/${this.name}/logs.json`, {
data: { offset, filters }
}).then(results => {
- return Ember.Object.create({
+ return EmberObject.create({
logs: results["logs"].map(log => GroupHistory.create(log)),
all_loaded: results["all_loaded"]
});
@@ -241,7 +244,7 @@ const Group = RestModel.extend({
p.user = User.create(p.user);
p.topic = Topic.create(p.topic);
p.category = Category.findById(p.category_id);
- return Ember.Object.create(p);
+ return EmberObject.create(p);
});
});
},
diff --git a/app/assets/javascripts/discourse/models/invite.js.es6 b/app/assets/javascripts/discourse/models/invite.js.es6
index 842a04a324..54baf013f5 100644
--- a/app/assets/javascripts/discourse/models/invite.js.es6
+++ b/app/assets/javascripts/discourse/models/invite.js.es6
@@ -1,6 +1,8 @@
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { userPath } from "discourse/lib/url";
+import { Promise } from "rsvp";
const Invite = Discourse.Model.extend({
rescind() {
@@ -31,7 +33,7 @@ Invite.reopenClass({
},
findInvitedBy(user, filter, search, offset) {
- if (!user) Ember.RSVP.resolve();
+ if (!user) Promise.resolve();
const data = {};
if (!Ember.isNone(filter)) data.filter = filter;
@@ -42,15 +44,15 @@ Invite.reopenClass({
data
}).then(result => {
result.invites = result.invites.map(i => Invite.create(i));
- return Ember.Object.create(result);
+ return EmberObject.create(result);
});
},
findInvitedCount(user) {
- if (!user) Ember.RSVP.resolve();
+ if (!user) Promise.resolve();
return ajax(userPath(`${user.username_lower}/invited_count.json`)).then(
- result => Ember.Object.create(result.counts)
+ result => EmberObject.create(result.counts)
);
},
diff --git a/app/assets/javascripts/discourse/models/login-method.js.es6 b/app/assets/javascripts/discourse/models/login-method.js.es6
index ce59db2450..0bfddf3951 100644
--- a/app/assets/javascripts/discourse/models/login-method.js.es6
+++ b/app/assets/javascripts/discourse/models/login-method.js.es6
@@ -1,7 +1,9 @@
+import EmberObject from "@ember/object";
import computed from "ember-addons/ember-computed-decorators";
import { updateCsrfToken } from "discourse/lib/ajax";
+import { Promise } from "rsvp";
-const LoginMethod = Ember.Object.extend({
+const LoginMethod = EmberObject.extend({
@computed
title() {
return this.title_override || I18n.t(`login.${this.name}.title`);
@@ -20,12 +22,12 @@ const LoginMethod = Ember.Object.extend({
doLogin({ reconnect = false } = {}) {
if (this.customLogin) {
this.customLogin();
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
if (this.custom_url) {
window.location = this.custom_url;
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
let authUrl = Discourse.getURL(`/auth/${this.name}`);
diff --git a/app/assets/javascripts/discourse/models/model.js.es6 b/app/assets/javascripts/discourse/models/model.js.es6
index c6a0b3ec20..5ce0eb2eaf 100644
--- a/app/assets/javascripts/discourse/models/model.js.es6
+++ b/app/assets/javascripts/discourse/models/model.js.es6
@@ -1,9 +1,11 @@
-const Model = Ember.Object.extend();
+import { isEmpty } from "@ember/utils";
+import EmberObject from "@ember/object";
+const Model = EmberObject.extend();
Model.reopenClass({
extractByKey(collection, klass) {
const retval = {};
- if (Ember.isEmpty(collection)) {
+ if (isEmpty(collection)) {
return retval;
}
diff --git a/app/assets/javascripts/discourse/models/nav-item.js.es6 b/app/assets/javascripts/discourse/models/nav-item.js.es6
index 85379d4bfc..5b36d3b4e4 100644
--- a/app/assets/javascripts/discourse/models/nav-item.js.es6
+++ b/app/assets/javascripts/discourse/models/nav-item.js.es6
@@ -118,6 +118,8 @@ const ExtraNavItem = NavItem.extend({
}
}),
+ count: 0,
+
customFilter: null
});
@@ -193,12 +195,46 @@ NavItem.reopenClass({
return item.customFilter.call(this, category, args);
});
+ let forceActive = false;
+
extraItems.forEach(item => {
+ if (item.init) {
+ item.init.call(this, item, category, args);
+ }
+
+ const before = item.before;
+ if (before) {
+ let i = 0;
+ for (i = 0; i < items.length; i++) {
+ if (items[i].name === before) {
+ break;
+ }
+ }
+ items.splice(i, 0, item);
+ } else {
+ items.push(item);
+ }
+
if (!item.customHref) return;
+
item.set("href", item.customHref.call(this, category, args));
+
+ if (item.forceActive && item.forceActive.call(this, category, args)) {
+ item.active = true;
+ forceActive = true;
+ } else {
+ item.active = undefined;
+ }
});
- return items.concat(extraItems);
+ if (forceActive) {
+ items.forEach(i => {
+ if (i.active === undefined) {
+ i.active = false;
+ }
+ });
+ }
+ return items;
}
});
@@ -213,5 +249,7 @@ export function customNavItemHref(cb) {
}
export function addNavItem(item) {
- NavItem.extraNavItems.push(ExtraNavItem.create(item));
+ const navItem = ExtraNavItem.create(item);
+ NavItem.extraNavItems.push(navItem);
+ return navItem;
}
diff --git a/app/assets/javascripts/discourse/models/post-action-type.js.es6 b/app/assets/javascripts/discourse/models/post-action-type.js.es6
index fc83f6282a..ef8541a168 100644
--- a/app/assets/javascripts/discourse/models/post-action-type.js.es6
+++ b/app/assets/javascripts/discourse/models/post-action-type.js.es6
@@ -1,7 +1,8 @@
+import { not } from "@ember/object/computed";
import RestModel from "discourse/models/rest";
export const MAX_MESSAGE_LENGTH = 500;
export default RestModel.extend({
- notCustomFlag: Ember.computed.not("is_custom_flag")
+ notCustomFlag: not("is_custom_flag")
});
diff --git a/app/assets/javascripts/discourse/models/post-stream.js.es6 b/app/assets/javascripts/discourse/models/post-stream.js.es6
index a3b42bcaeb..6baafb909b 100644
--- a/app/assets/javascripts/discourse/models/post-stream.js.es6
+++ b/app/assets/javascripts/discourse/models/post-stream.js.es6
@@ -1,9 +1,13 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
+import { or, not, and } from "@ember/object/computed";
import { ajax } from "discourse/lib/ajax";
import DiscourseURL from "discourse/lib/url";
import RestModel from "discourse/models/rest";
import PostsWithPlaceholders from "discourse/lib/posts-with-placeholders";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { loadTopicView } from "discourse/models/topic";
+import { Promise } from "rsvp";
export default RestModel.extend({
_identityMap: null,
@@ -43,13 +47,8 @@ export default RestModel.extend({
});
},
- loading: Ember.computed.or(
- "loadingAbove",
- "loadingBelow",
- "loadingFilter",
- "stagingPost"
- ),
- notLoading: Ember.computed.not("loading"),
+ loading: or("loadingAbove", "loadingBelow", "loadingFilter", "stagingPost"),
+ notLoading: not("loading"),
@computed("isMegaTopic", "stream.length", "topic.highest_post_number")
filteredPostsCount(isMegaTopic, streamLength, topicHighestPostNumber) {
@@ -66,16 +65,8 @@ export default RestModel.extend({
return hasPosts && filteredPostsCount > 0;
},
- canAppendMore: Ember.computed.and(
- "notLoading",
- "hasPosts",
- "lastPostNotLoaded"
- ),
- canPrependMore: Ember.computed.and(
- "notLoading",
- "hasPosts",
- "firstPostNotLoaded"
- ),
+ canAppendMore: and("notLoading", "hasPosts", "lastPostNotLoaded"),
+ canPrependMore: and("notLoading", "hasPosts", "firstPostNotLoaded"),
@computed("hasLoadedData", "firstPostId", "posts.[]")
firstPostPresent(hasLoadedData, firstPostId) {
@@ -85,7 +76,7 @@ export default RestModel.extend({
return !!this.posts.findBy("id", firstPostId);
},
- firstPostNotLoaded: Ember.computed.not("firstPostPresent"),
+ firstPostNotLoaded: not("firstPostPresent"),
firstId: null,
lastId: null,
@@ -112,7 +103,7 @@ export default RestModel.extend({
return !!this.posts.findBy("id", lastPostId);
},
- lastPostNotLoaded: Ember.computed.not("loadedAllPosts"),
+ lastPostNotLoaded: not("loadedAllPosts"),
/**
Returns a JS Object of current stream filter options. It should match the query
@@ -126,7 +117,7 @@ export default RestModel.extend({
}
const userFilters = this.userFilters;
- if (!Ember.isEmpty(userFilters)) {
+ if (!isEmpty(userFilters)) {
result.username_filters = userFilters.join(",");
}
@@ -265,7 +256,7 @@ export default RestModel.extend({
} else {
const postWeWant = this.posts.findBy("post_number", opts.nearPost);
if (postWeWant) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
}
@@ -327,7 +318,7 @@ export default RestModel.extend({
});
}
}
- return Ember.RSVP.resolve();
+ return Promise.resolve();
},
// Fill in a gap of posts after a particular post
@@ -343,14 +334,14 @@ export default RestModel.extend({
this.stream.arrayContentDidChange();
});
}
- return Ember.RSVP.resolve();
+ return Promise.resolve();
},
// Appends the next window of posts to the stream. Call it when scrolling downwards.
appendMore() {
// Make sure we can append more posts
if (!this.canAppendMore) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
const postsWithPlaceholders = this.postsWithPlaceholders;
@@ -373,7 +364,7 @@ export default RestModel.extend({
});
} else {
const postIds = this.nextWindow;
- if (Ember.isEmpty(postIds)) return Ember.RSVP.resolve();
+ if (isEmpty(postIds)) return Promise.resolve();
this.set("loadingBelow", true);
postsWithPlaceholders.appending(postIds);
@@ -393,7 +384,7 @@ export default RestModel.extend({
prependMore() {
// Make sure we can append more posts
if (!this.canPrependMore) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
if (this.isMegaTopic) {
@@ -414,7 +405,7 @@ export default RestModel.extend({
});
} else {
const postIds = this.previousWindow;
- if (Ember.isEmpty(postIds)) return Ember.RSVP.resolve();
+ if (isEmpty(postIds)) return Promise.resolve();
this.set("loadingAbove", true);
return this.findPostsByIds(postIds.reverse())
@@ -532,7 +523,7 @@ export default RestModel.extend({
},
removePosts(posts) {
- if (Ember.isEmpty(posts)) {
+ if (isEmpty(posts)) {
return;
}
@@ -590,7 +581,7 @@ export default RestModel.extend({
have no filters.
**/
triggerNewPostInStream(postId) {
- const resolved = Ember.RSVP.Promise.resolve();
+ const resolved = Promise.resolve();
if (!postId) {
return resolved;
@@ -690,13 +681,13 @@ export default RestModel.extend({
this.removePosts([existing]);
});
}
- return Ember.RSVP.Promise.resolve();
+ return Promise.resolve();
},
triggerChangedPost(postId, updatedAt, opts) {
opts = opts || {};
- const resolved = Ember.RSVP.Promise.resolve();
+ const resolved = Promise.resolve();
if (!postId) {
return resolved;
}
@@ -717,7 +708,7 @@ export default RestModel.extend({
},
triggerReadPost(postId, readersCount) {
- const resolved = Ember.RSVP.Promise.resolve();
+ const resolved = Promise.resolve();
resolved.then(() => {
const post = this.findLoadedPost(postId);
if (post && readersCount > post.readers_count) {
@@ -893,12 +884,12 @@ export default RestModel.extend({
than you supplied if the post has already been loaded.
**/
storePost(post) {
- // Calling `Ember.get(undefined)` raises an error
+ // Calling `get(undefined)` raises an error
if (!post) {
return;
}
- const postId = Ember.get(post, "id");
+ const postId = get(post, "id");
if (postId) {
const existing = this._identityMap[post.get("id")];
@@ -942,7 +933,7 @@ export default RestModel.extend({
this.set("topic.suggested_topics", result.suggested_topics);
}
- const posts = Ember.get(result, "post_stream.posts");
+ const posts = get(result, "post_stream.posts");
if (posts) {
posts.forEach(p => {
@@ -967,8 +958,8 @@ export default RestModel.extend({
},
loadIntoIdentityMap(postIds) {
- if (Ember.isEmpty(postIds)) {
- return Ember.RSVP.resolve([]);
+ if (isEmpty(postIds)) {
+ return Promise.resolve([]);
}
let includeSuggested = !this.get("topic.suggested_topics");
@@ -982,7 +973,7 @@ export default RestModel.extend({
this.set("topic.suggested_topics", result.suggested_topics);
}
- const posts = Ember.get(result, "post_stream.posts");
+ const posts = get(result, "post_stream.posts");
if (posts) {
posts.forEach(p => this.storePost(store.createRecord("post", p)));
@@ -1039,12 +1030,12 @@ export default RestModel.extend({
excerpt(streamPosition) {
if (this.isMegaTopic) {
- return new Ember.RSVP.Promise(resolve => resolve(""));
+ return new Promise(resolve => resolve(""));
}
const stream = this.stream;
- return new Ember.RSVP.Promise((resolve, reject) => {
+ return new Promise((resolve, reject) => {
let excerpt = this._excerpts && this._excerpts[stream[streamPosition]];
if (excerpt) {
diff --git a/app/assets/javascripts/discourse/models/post.js.es6 b/app/assets/javascripts/discourse/models/post.js.es6
index a82cef491d..4fbfcdeea0 100644
--- a/app/assets/javascripts/discourse/models/post.js.es6
+++ b/app/assets/javascripts/discourse/models/post.js.es6
@@ -1,3 +1,7 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
+import { equal, and, or, not } from "@ember/object/computed";
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import RestModel from "discourse/models/rest";
import { popupAjaxError } from "discourse/lib/ajax-error";
@@ -9,6 +13,7 @@ import { postUrl } from "discourse/lib/utilities";
import { cookAsync } from "discourse/lib/text";
import { userPath } from "discourse/lib/url";
import Composer from "discourse/models/composer";
+import { Promise } from "rsvp";
const Post = RestModel.extend({
// TODO: Remove this once one instantiate all `Discourse.Post` models via the store.
@@ -35,13 +40,13 @@ const Post = RestModel.extend({
}
},
- new_user: Ember.computed.equal("trust_level", 0),
- firstPost: Ember.computed.equal("post_number", 1),
+ new_user: equal("trust_level", 0),
+ firstPost: equal("post_number", 1),
// Posts can show up as deleted if the topic is deleted
- deletedViaTopic: Ember.computed.and("firstPost", "topic.deleted_at"),
- deleted: Ember.computed.or("deleted_at", "deletedViaTopic"),
- notDeleted: Ember.computed.not("deleted"),
+ deletedViaTopic: and("firstPost", "topic.deleted_at"),
+ deleted: or("deleted_at", "deletedViaTopic"),
+ notDeleted: not("deleted"),
@computed("name", "username")
showName(name, username) {
@@ -91,7 +96,7 @@ const Post = RestModel.extend({
@computed("link_counts.@each.internal")
internalLinks() {
- if (Ember.isEmpty(this.link_counts)) return null;
+ if (isEmpty(this.link_counts)) return null;
return this.link_counts.filterBy("internal").filterBy("title");
},
@@ -226,7 +231,7 @@ const Post = RestModel.extend({
});
}
- return promise || Ember.RSVP.Promise.resolve();
+ return promise || Promise.resolve();
},
/**
@@ -279,7 +284,7 @@ const Post = RestModel.extend({
if (key === "reply_to_user" && value && oldValue) {
skip =
value.username === oldValue.username ||
- Ember.get(value, "username") === Ember.get(oldValue, "username");
+ get(value, "username") === get(oldValue, "username");
}
if (!skip) {
@@ -346,7 +351,7 @@ const Post = RestModel.extend({
Post.reopenClass({
munge(json) {
if (json.actions_summary) {
- const lookup = Ember.Object.create();
+ const lookup = EmberObject.create();
// this area should be optimized, it is creating way too many objects per post
json.actions_summary = json.actions_summary.map(a => {
@@ -394,7 +399,7 @@ Post.reopenClass({
loadRevision(postId, version) {
return ajax(`/posts/${postId}/revisions/${version}.json`).then(result =>
- Ember.Object.create(result)
+ EmberObject.create(result)
);
},
diff --git a/app/assets/javascripts/discourse/models/rest.js.es6 b/app/assets/javascripts/discourse/models/rest.js.es6
index 8b731f584f..a140dad504 100644
--- a/app/assets/javascripts/discourse/models/rest.js.es6
+++ b/app/assets/javascripts/discourse/models/rest.js.es6
@@ -1,6 +1,10 @@
-const RestModel = Ember.Object.extend({
- isNew: Ember.computed.equal("__state", "new"),
- isCreated: Ember.computed.equal("__state", "created"),
+import { equal } from "@ember/object/computed";
+import EmberObject from "@ember/object";
+import { Promise } from "rsvp";
+
+const RestModel = EmberObject.extend({
+ isNew: equal("__state", "new"),
+ isCreated: equal("__state", "created"),
isSaving: false,
beforeCreate() {},
@@ -8,7 +12,7 @@ const RestModel = Ember.Object.extend({
update(props) {
if (this.isSaving) {
- return Ember.RSVP.reject();
+ return Promise.reject();
}
props = props || this.updateProperties();
@@ -36,7 +40,7 @@ const RestModel = Ember.Object.extend({
_saveNew(props) {
if (this.isSaving) {
- return Ember.RSVP.reject();
+ return Promise.reject();
}
props = props || this.createProperties();
diff --git a/app/assets/javascripts/discourse/models/result-set.js.es6 b/app/assets/javascripts/discourse/models/result-set.js.es6
index dc9f1f9ec4..436abfd2de 100644
--- a/app/assets/javascripts/discourse/models/result-set.js.es6
+++ b/app/assets/javascripts/discourse/models/result-set.js.es6
@@ -1,4 +1,5 @@
import computed from "ember-addons/ember-computed-decorators";
+import { Promise } from "rsvp";
export default Ember.ArrayProxy.extend({
loading: false,
@@ -34,7 +35,7 @@ export default Ember.ArrayProxy.extend({
.finally(() => this.set("loadingMore", false));
}
- return Ember.RSVP.resolve();
+ return Promise.resolve();
},
refresh() {
diff --git a/app/assets/javascripts/discourse/models/reviewable-history.js.es6 b/app/assets/javascripts/discourse/models/reviewable-history.js.es6
index 0b1b14f54e..dec1f37be5 100644
--- a/app/assets/javascripts/discourse/models/reviewable-history.js.es6
+++ b/app/assets/javascripts/discourse/models/reviewable-history.js.es6
@@ -1,3 +1,4 @@
+import { equal } from "@ember/object/computed";
import RestModel from "discourse/models/rest";
export const CREATED = 0;
@@ -5,5 +6,5 @@ export const TRANSITIONED_TO = 1;
export const EDITED = 2;
export default RestModel.extend({
- created: Ember.computed.equal("reviewable_history_type", CREATED)
+ created: equal("reviewable_history_type", CREATED)
});
diff --git a/app/assets/javascripts/discourse/models/reviewable.js.es6 b/app/assets/javascripts/discourse/models/reviewable.js.es6
index 25fc62f63d..892822c59e 100644
--- a/app/assets/javascripts/discourse/models/reviewable.js.es6
+++ b/app/assets/javascripts/discourse/models/reviewable.js.es6
@@ -2,6 +2,7 @@ import { ajax } from "discourse/lib/ajax";
import RestModel from "discourse/models/rest";
import computed from "ember-addons/ember-computed-decorators";
import Category from "discourse/models/category";
+import { Promise } from "rsvp";
export const PENDING = 0;
export const APPROVED = 1;
@@ -25,7 +26,7 @@ export default RestModel.extend({
update(updates) {
// If no changes, do nothing
if (Object.keys(updates).length === 0) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
let adapter = this.store.adapterFor("reviewable");
diff --git a/app/assets/javascripts/discourse/models/site.js.es6 b/app/assets/javascripts/discourse/models/site.js.es6
index 1089956d6c..07dc4d72b3 100644
--- a/app/assets/javascripts/discourse/models/site.js.es6
+++ b/app/assets/javascripts/discourse/models/site.js.es6
@@ -1,3 +1,7 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
+import { alias, sort } from "@ember/object/computed";
+import EmberObject from "@ember/object";
import computed from "ember-addons/ember-computed-decorators";
import Archetype from "discourse/models/archetype";
import PostActionType from "discourse/models/post-action-type";
@@ -6,7 +10,7 @@ import RestModel from "discourse/models/rest";
import PreloadStore from "preload-store";
const Site = RestModel.extend({
- isReadOnly: Ember.computed.alias("is_readonly"),
+ isReadOnly: alias("is_readonly"),
init() {
this._super(...arguments);
@@ -30,14 +34,14 @@ const Site = RestModel.extend({
return postActionTypes.filterBy("is_flag", true);
},
- categoriesByCount: Ember.computed.sort("categories", "topicCountDesc"),
+ categoriesByCount: sort("categories", "topicCountDesc"),
collectUserFields(fields) {
fields = fields || {};
let siteFields = this.user_fields;
- if (!Ember.isEmpty(siteFields)) {
+ if (!isEmpty(siteFields)) {
return siteFields.map(f => {
let value = fields ? fields[f.id.toString()] : null;
value = value || "—".htmlSafe();
@@ -107,7 +111,7 @@ const Site = RestModel.extend({
updateCategory(newCategory) {
const categories = this.categories;
- const categoryId = Ember.get(newCategory, "id");
+ const categoryId = get(newCategory, "id");
const existingCategory = categories.findBy("id", categoryId);
// Don't update null permissions
@@ -179,7 +183,7 @@ Site.reopenClass(Singleton, {
}
if (result.post_action_types) {
- result.postActionByIdLookup = Ember.Object.create();
+ result.postActionByIdLookup = EmberObject.create();
result.post_action_types = result.post_action_types.map(p => {
const actionType = PostActionType.create(p);
result.postActionByIdLookup.set("action" + p.id, actionType);
@@ -188,7 +192,7 @@ Site.reopenClass(Singleton, {
}
if (result.topic_flag_types) {
- result.topicFlagByIdLookup = Ember.Object.create();
+ result.topicFlagByIdLookup = EmberObject.create();
result.topic_flag_types = result.topic_flag_types.map(p => {
const actionType = PostActionType.create(p);
result.topicFlagByIdLookup.set("action" + p.id, actionType);
@@ -204,9 +208,7 @@ Site.reopenClass(Singleton, {
}
if (result.user_fields) {
- result.user_fields = result.user_fields.map(uf =>
- Ember.Object.create(uf)
- );
+ result.user_fields = result.user_fields.map(uf => EmberObject.create(uf));
}
return result;
diff --git a/app/assets/javascripts/discourse/models/static-page.js.es6 b/app/assets/javascripts/discourse/models/static-page.js.es6
index a8cdb2507b..57bb3cc2df 100644
--- a/app/assets/javascripts/discourse/models/static-page.js.es6
+++ b/app/assets/javascripts/discourse/models/static-page.js.es6
@@ -1,9 +1,10 @@
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
-const StaticPage = Ember.Object.extend();
+const StaticPage = EmberObject.extend();
StaticPage.reopenClass({
find(path) {
- return new Ember.RSVP.Promise(resolve => {
+ return new Promise(resolve => {
// Models shouldn't really be doing Ajax request, but this is a huge speed boost if we
// preload content.
const $preloaded = $('noscript[data-path="/' + path + '"]');
diff --git a/app/assets/javascripts/discourse/models/store.js.es6 b/app/assets/javascripts/discourse/models/store.js.es6
index 96a96f502f..39a5ce1434 100644
--- a/app/assets/javascripts/discourse/models/store.js.es6
+++ b/app/assets/javascripts/discourse/models/store.js.es6
@@ -1,7 +1,10 @@
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import RestModel from "discourse/models/rest";
import ResultSet from "discourse/models/result-set";
import { getRegister } from "discourse-common/lib/get-owner";
+import { underscore } from "@ember/string";
+import { set } from "@ember/object";
let _identityMap;
@@ -44,7 +47,7 @@ function findAndRemoveMap(type, id) {
flushMap();
-export default Ember.Object.extend({
+export default EmberObject.extend({
_plurals: {
"post-reply": "post-replies",
"post-reply-history": "post_reply_histories",
@@ -92,7 +95,8 @@ export default Ember.Object.extend({
if (typeof findArgs === "object") {
return this._resultSet(type, result, findArgs);
} else {
- return this._hydrate(type, result[Ember.String.underscore(type)], result);
+ const apiName = this.adapterFor(type).apiNameFor(type);
+ return this._hydrate(type, result[underscore(apiName)], result);
}
},
@@ -146,8 +150,9 @@ export default Ember.Object.extend({
},
refreshResults(resultSet, type, url) {
+ const adapter = this.adapterFor(type);
return ajax(url).then(result => {
- const typeName = Ember.String.underscore(this.pluralize(type));
+ const typeName = underscore(this.pluralize(adapter.apiNameFor(type)));
const content = result[typeName].map(obj =>
this._hydrate(type, obj, result)
);
@@ -156,8 +161,9 @@ export default Ember.Object.extend({
},
appendResults(resultSet, type, url) {
+ const adapter = this.adapterFor(type);
return ajax(url).then(result => {
- let typeName = Ember.String.underscore(this.pluralize(type));
+ const typeName = underscore(this.pluralize(adapter.apiNameFor(type)));
let pageTarget = result.meta || result;
let totalRows =
@@ -198,7 +204,7 @@ export default Ember.Object.extend({
// If the record is new, don't perform an Ajax call
if (record.get("isNew")) {
removeMap(type, record.get("id"));
- return Ember.RSVP.Promise.resolve(true);
+ return Promise.resolve(true);
}
return this.adapterFor(type)
@@ -210,7 +216,8 @@ export default Ember.Object.extend({
},
_resultSet(type, result, findArgs) {
- const typeName = Ember.String.underscore(this.pluralize(type));
+ const adapter = this.adapterFor(type);
+ const typeName = underscore(this.pluralize(adapter.apiNameFor(type)));
const content = result[typeName].map(obj =>
this._hydrate(type, obj, result)
);
@@ -312,7 +319,7 @@ export default Ember.Object.extend({
obj[subType] = hydrated;
delete obj[k];
} else {
- Ember.set(obj, subType, null);
+ set(obj, subType, null);
}
}
}
diff --git a/app/assets/javascripts/discourse/models/tag-group.js.es6 b/app/assets/javascripts/discourse/models/tag-group.js.es6
index 6d0579a1b9..e42ccee9dd 100644
--- a/app/assets/javascripts/discourse/models/tag-group.js.es6
+++ b/app/assets/javascripts/discourse/models/tag-group.js.es6
@@ -1,77 +1,18 @@
-import { ajax } from "discourse/lib/ajax";
import RestModel from "discourse/models/rest";
import computed from "ember-addons/ember-computed-decorators";
import PermissionType from "discourse/models/permission-type";
export default RestModel.extend({
- @computed("name", "tag_names", "saving")
- disableSave(name, tagNames, saving) {
- return saving || Ember.isEmpty(name) || Ember.isEmpty(tagNames);
- },
-
- @computed("id")
- disableDelete(id) {
- return !parseInt(id);
- },
-
@computed("permissions")
- permissionName: {
- get(permissions) {
- if (!permissions) return "public";
+ permissionName(permissions) {
+ if (!permissions) return "public";
- if (permissions["everyone"] === PermissionType.FULL) {
- return "public";
- } else if (permissions["everyone"] === PermissionType.READONLY) {
- return "visible";
- } else {
- return "private";
- }
- },
-
- set(value) {
- if (value === "private") {
- this.set("permissions", { staff: PermissionType.FULL });
- } else if (value === "visible") {
- this.set("permissions", {
- staff: PermissionType.FULL,
- everyone: PermissionType.READONLY
- });
- } else {
- this.set("permissions", { everyone: PermissionType.FULL });
- }
+ if (permissions["everyone"] === PermissionType.FULL) {
+ return "public";
+ } else if (permissions["everyone"] === PermissionType.READONLY) {
+ return "visible";
+ } else {
+ return "private";
}
- },
-
- save() {
- this.set("savingStatus", I18n.t("saving"));
- this.set("saving", true);
-
- const isNew = this.id === "new";
- const url = isNew ? "/tag_groups" : `/tag_groups/${this.id}`;
- const data = this.getProperties(
- "name",
- "tag_names",
- "parent_tag_name",
- "one_per_topic",
- "permissions"
- );
-
- return ajax(url, {
- data,
- type: isNew ? "POST" : "PUT"
- })
- .then(result => {
- if (result.tag_group && result.tag_group.id) {
- this.set("id", result.tag_group.id);
- }
- })
- .finally(() => {
- this.set("savingStatus", I18n.t("saved"));
- this.set("saving", false);
- });
- },
-
- destroy() {
- return ajax(`/tag_groups/${this.id}`, { type: "DELETE" });
}
});
diff --git a/app/assets/javascripts/discourse/models/topic-details.js.es6 b/app/assets/javascripts/discourse/models/topic-details.js.es6
index 9f486f0712..0622cacb69 100644
--- a/app/assets/javascripts/discourse/models/topic-details.js.es6
+++ b/app/assets/javascripts/discourse/models/topic-details.js.es6
@@ -1,3 +1,4 @@
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import computed from "ember-addons/ember-computed-decorators";
@@ -23,7 +24,7 @@ const TopicDetails = RestModel.extend({
if (details.participants) {
details.participants = details.participants.map(function(p) {
p.topic = topic;
- return Ember.Object.create(p);
+ return EmberObject.create(p);
});
}
diff --git a/app/assets/javascripts/discourse/models/topic-list.js.es6 b/app/assets/javascripts/discourse/models/topic-list.js.es6
index e12a90e77e..da01a6899d 100644
--- a/app/assets/javascripts/discourse/models/topic-list.js.es6
+++ b/app/assets/javascripts/discourse/models/topic-list.js.es6
@@ -1,7 +1,10 @@
+import { notEmpty } from "@ember/object/computed";
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import RestModel from "discourse/models/rest";
import Model from "discourse/models/model";
import { getOwner } from "discourse-common/lib/get-owner";
+import { Promise } from "rsvp";
// Whether to show the category badge in topic lists
function displayCategoryInList(site, category) {
@@ -22,7 +25,7 @@ function displayCategoryInList(site, category) {
}
const TopicList = RestModel.extend({
- canLoadMore: Ember.computed.notEmpty("more_topics_url"),
+ canLoadMore: notEmpty("more_topics_url"),
forEachNew(topics, callback) {
const topicIds = [];
@@ -52,7 +55,7 @@ const TopicList = RestModel.extend({
loadMore() {
if (this.loadingMore) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
let moreUrl = this.more_topics_url;
@@ -95,7 +98,7 @@ const TopicList = RestModel.extend({
});
} else {
// Return a promise indicating no more results
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
},
@@ -135,7 +138,7 @@ TopicList.reopenClass({
const categories = Discourse.Category.list(),
users = Model.extractByKey(result.users, Discourse.User),
- groups = Model.extractByKey(result.primary_groups, Ember.Object);
+ groups = Model.extractByKey(result.primary_groups, EmberObject);
return result.topic_list[listKey].map(t => {
t.category = categories.findBy("id", t.category_id);
diff --git a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6
index 5c726069d3..89eab6119a 100644
--- a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6
+++ b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6
@@ -1,3 +1,5 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
import { NotificationLevels } from "discourse/lib/notification-levels";
import {
default as computed,
@@ -215,7 +217,7 @@ const TopicTrackingState = Discourse.Model.extend({
// If we have a cached topic list, we can update it from our tracking information.
updateTopics(topics) {
- if (Ember.isEmpty(topics)) {
+ if (isEmpty(topics)) {
return;
}
@@ -389,8 +391,8 @@ const TopicTrackingState = Discourse.Model.extend({
);
}
- let categoryId = category ? Ember.get(category, "id") : null;
- let categoryName = category ? Ember.get(category, "name") : null;
+ let categoryId = category ? get(category, "id") : null;
+ let categoryName = category ? get(category, "name") : null;
if (name === "new") {
return this.countNew(categoryId);
diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6
index 1af3697106..f4bf6c6533 100644
--- a/app/assets/javascripts/discourse/models/topic.js.es6
+++ b/app/assets/javascripts/discourse/models/topic.js.es6
@@ -1,3 +1,6 @@
+import { get } from "@ember/object";
+import { not, notEmpty, equal, and, or } from "@ember/object/computed";
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import { flushMap } from "discourse/models/store";
import RestModel from "discourse/models/rest";
@@ -194,8 +197,8 @@ const Topic = RestModel.extend({
});
},
- invisible: Ember.computed.not("visible"),
- deleted: Ember.computed.notEmpty("deleted_at"),
+ invisible: not("visible"),
+ deleted: notEmpty("deleted_at"),
@computed("id")
searchContext(id) {
@@ -335,8 +338,8 @@ const Topic = RestModel.extend({
return Discourse.Site.currentProp("archetypes").findBy("id", archetype);
},
- isPrivateMessage: Ember.computed.equal("archetype", "private_message"),
- isBanner: Ember.computed.equal("archetype", "banner"),
+ isPrivateMessage: equal("archetype", "private_message"),
+ isBanner: equal("archetype", "banner"),
toggleStatus(property) {
this.toggleProperty(property);
@@ -371,12 +374,12 @@ const Topic = RestModel.extend({
toggleBookmark() {
if (this.bookmarking) {
- return Ember.RSVP.Promise.resolve();
+ return Promise.resolve();
}
this.set("bookmarking", true);
const stream = this.postStream;
- const posts = Ember.get(stream, "posts");
+ const posts = get(stream, "posts");
const firstPost =
posts && posts[0] && posts[0].get("post_number") === 1 && posts[0];
const bookmark = !this.bookmarked;
@@ -414,7 +417,7 @@ const Topic = RestModel.extend({
);
}
- return new Ember.RSVP.Promise(resolve => {
+ return new Promise(resolve => {
if (unbookmarkedPosts.length > 1) {
bootbox.confirm(
I18n.t("bookmarks.confirm_clear"),
@@ -495,10 +498,7 @@ const Topic = RestModel.extend({
);
},
- isPinnedUncategorized: Ember.computed.and(
- "pinned",
- "category.isUncategorizedCategory"
- ),
+ isPinnedUncategorized: and("pinned", "category.isUncategorizedCategory"),
clearPin() {
// Clear the pin optimistically from the object
@@ -537,7 +537,7 @@ const Topic = RestModel.extend({
return emojiUnescape(excerpt);
},
- hasExcerpt: Ember.computed.notEmpty("excerpt"),
+ hasExcerpt: notEmpty("excerpt"),
@computed("excerpt")
excerptTruncated(excerpt) {
@@ -545,7 +545,8 @@ const Topic = RestModel.extend({
},
readLastPost: propertyEqual("last_read_post_number", "highest_post_number"),
- canClearPin: Ember.computed.and("pinned", "readLastPost"),
+ canClearPin: and("pinned", "readLastPost"),
+ canEditTags: or("details.can_edit", "details.can_edit_tags"),
archiveMessage() {
this.set("archiving", true);
@@ -610,6 +611,17 @@ const Topic = RestModel.extend({
return ajax(`/t/${this.id}/reset-bump-date`, { type: "PUT" }).catch(
popupAjaxError
);
+ },
+
+ updateTags(tags) {
+ if (!tags || tags.length === 0) {
+ tags = [""];
+ }
+
+ return ajax(`/t/${this.id}/tags`, {
+ type: "PUT",
+ data: { tags: tags }
+ });
}
});
@@ -623,7 +635,7 @@ Topic.reopenClass({
createActionSummary(result) {
if (result.actions_summary) {
- const lookup = Ember.Object.create();
+ const lookup = EmberObject.create();
result.actions_summary = result.actions_summary.map(a => {
a.post = result;
a.actionType = Discourse.Site.current().postActionTypeById(a.id);
diff --git a/app/assets/javascripts/discourse/models/user-action.js.es6 b/app/assets/javascripts/discourse/models/user-action.js.es6
index 50600bc7fb..5ca07e7025 100644
--- a/app/assets/javascripts/discourse/models/user-action.js.es6
+++ b/app/assets/javascripts/discourse/models/user-action.js.es6
@@ -1,3 +1,4 @@
+import { or, equal, and } from "@ember/object/computed";
import RestModel from "discourse/models/rest";
import { on } from "ember-addons/ember-computed-decorators";
import computed from "ember-addons/ember-computed-decorators";
@@ -75,9 +76,9 @@ const UserAction = RestModel.extend({
return targetUsername === Discourse.User.currentProp("username");
},
- presentName: Ember.computed.or("name", "username"),
- targetDisplayName: Ember.computed.or("target_name", "target_username"),
- actingDisplayName: Ember.computed.or("acting_name", "acting_username"),
+ presentName: or("name", "username"),
+ targetDisplayName: or("target_name", "target_username"),
+ actingDisplayName: or("acting_name", "acting_username"),
@computed("target_username")
targetUserUrl(username) {
@@ -104,22 +105,16 @@ const UserAction = RestModel.extend({
return postUrl(this.slug, this.topic_id, this.reply_to_post_number);
},
- replyType: Ember.computed.equal("action_type", UserActionTypes.replies),
- postType: Ember.computed.equal("action_type", UserActionTypes.posts),
- topicType: Ember.computed.equal("action_type", UserActionTypes.topics),
- bookmarkType: Ember.computed.equal("action_type", UserActionTypes.bookmarks),
- messageSentType: Ember.computed.equal(
- "action_type",
- UserActionTypes.messages_sent
- ),
- messageReceivedType: Ember.computed.equal(
- "action_type",
- UserActionTypes.messages_received
- ),
- mentionType: Ember.computed.equal("action_type", UserActionTypes.mentions),
- isPM: Ember.computed.or("messageSentType", "messageReceivedType"),
- postReplyType: Ember.computed.or("postType", "replyType"),
- removableBookmark: Ember.computed.and("bookmarkType", "sameUser"),
+ replyType: equal("action_type", UserActionTypes.replies),
+ postType: equal("action_type", UserActionTypes.posts),
+ topicType: equal("action_type", UserActionTypes.topics),
+ bookmarkType: equal("action_type", UserActionTypes.bookmarks),
+ messageSentType: equal("action_type", UserActionTypes.messages_sent),
+ messageReceivedType: equal("action_type", UserActionTypes.messages_received),
+ mentionType: equal("action_type", UserActionTypes.mentions),
+ isPM: or("messageSentType", "messageReceivedType"),
+ postReplyType: or("postType", "replyType"),
+ removableBookmark: and("bookmarkType", "sameUser"),
addChild(action) {
let groups = this.childGroups;
diff --git a/app/assets/javascripts/discourse/models/user-badge.js.es6 b/app/assets/javascripts/discourse/models/user-badge.js.es6
index a8850674a4..69e88caf2e 100644
--- a/app/assets/javascripts/discourse/models/user-badge.js.es6
+++ b/app/assets/javascripts/discourse/models/user-badge.js.es6
@@ -1,6 +1,7 @@
import { ajax } from "discourse/lib/ajax";
import Badge from "discourse/models/badge";
import computed from "ember-addons/ember-computed-decorators";
+import { Promise } from "rsvp";
const UserBadge = Discourse.Model.extend({
@computed
@@ -96,7 +97,7 @@ UserBadge.reopenClass({
**/
findByUsername: function(username, options) {
if (!username) {
- return Ember.RSVP.resolve([]);
+ return Promise.resolve([]);
}
var url = "/user-badges/" + username + ".json";
if (options && options.grouped) {
diff --git a/app/assets/javascripts/discourse/models/user-drafts-stream.js.es6 b/app/assets/javascripts/discourse/models/user-drafts-stream.js.es6
index c384b49569..ee1d3cccad 100644
--- a/app/assets/javascripts/discourse/models/user-drafts-stream.js.es6
+++ b/app/assets/javascripts/discourse/models/user-drafts-stream.js.es6
@@ -4,7 +4,7 @@ import RestModel from "discourse/models/rest";
import UserDraft from "discourse/models/user-draft";
import { emojiUnescape } from "discourse/lib/text";
import computed from "ember-addons/ember-computed-decorators";
-
+import { Promise } from "rsvp";
import {
NEW_TOPIC_KEY,
NEW_PRIVATE_MESSAGE_KEY
@@ -55,11 +55,11 @@ export default RestModel.extend({
const lastLoadedUrl = this.lastLoadedUrl;
if (lastLoadedUrl === findUrl) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
if (this.loading) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
this.set("loading", true);
diff --git a/app/assets/javascripts/discourse/models/user-posts-stream.js.es6 b/app/assets/javascripts/discourse/models/user-posts-stream.js.es6
index 7521b82dce..74cadcb455 100644
--- a/app/assets/javascripts/discourse/models/user-posts-stream.js.es6
+++ b/app/assets/javascripts/discourse/models/user-posts-stream.js.es6
@@ -2,6 +2,7 @@ import { on } from "ember-addons/ember-computed-decorators";
import { ajax } from "discourse/lib/ajax";
import { url } from "discourse/lib/computed";
import UserAction from "discourse/models/user-action";
+import { Promise } from "rsvp";
export default Discourse.Model.extend({
loaded: false,
@@ -24,7 +25,7 @@ export default Discourse.Model.extend({
filterBy(opts) {
if (this.loaded && this.filter === opts.filter) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
this.setProperties(
@@ -43,7 +44,7 @@ export default Discourse.Model.extend({
findItems() {
if (this.loading || !this.canLoadMore) {
- return Ember.RSVP.reject();
+ return Promise.reject();
}
this.set("loading", true);
diff --git a/app/assets/javascripts/discourse/models/user-stream.js.es6 b/app/assets/javascripts/discourse/models/user-stream.js.es6
index 35e44cc661..1a90ebd940 100644
--- a/app/assets/javascripts/discourse/models/user-stream.js.es6
+++ b/app/assets/javascripts/discourse/models/user-stream.js.es6
@@ -3,6 +3,7 @@ import { url } from "discourse/lib/computed";
import RestModel from "discourse/models/rest";
import UserAction from "discourse/models/user-action";
import { emojiUnescape } from "discourse/lib/text";
+import { Promise } from "rsvp";
import {
default as computed,
on
@@ -92,11 +93,11 @@ export default RestModel.extend({
// Don't load the same stream twice. We're probably at the end.
const lastLoadedUrl = this.lastLoadedUrl;
if (lastLoadedUrl === findUrl) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
if (this.loading) {
- return Ember.RSVP.resolve();
+ return Promise.resolve();
}
this.set("loading", true);
diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6
index a16b24f80e..af2a0dd2fc 100644
--- a/app/assets/javascripts/discourse/models/user.js.es6
+++ b/app/assets/javascripts/discourse/models/user.js.es6
@@ -1,3 +1,6 @@
+import { isEmpty } from "@ember/utils";
+import { gt, equal, or } from "@ember/object/computed";
+import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import { url } from "discourse/lib/computed";
import RestModel from "discourse/models/rest";
@@ -20,6 +23,8 @@ import PreloadStore from "preload-store";
import { defaultHomepage } from "discourse/lib/utilities";
import { userPath } from "discourse/lib/url";
import Category from "discourse/models/category";
+import { Promise } from "rsvp";
+import { getProperties } from "@ember/object";
export const SECOND_FACTOR_METHODS = {
TOTP: 1,
@@ -30,9 +35,9 @@ export const SECOND_FACTOR_METHODS = {
const isForever = dt => moment().diff(dt, "years") < -500;
const User = RestModel.extend({
- hasPMs: Ember.computed.gt("private_messages_stats.all", 0),
- hasStartedPMs: Ember.computed.gt("private_messages_stats.mine", 0),
- hasUnreadPMs: Ember.computed.gt("private_messages_stats.unread", 0),
+ hasPMs: gt("private_messages_stats.all", 0),
+ hasStartedPMs: gt("private_messages_stats.mine", 0),
+ hasUnreadPMs: gt("private_messages_stats.unread", 0),
redirected_to_top: {
reason: null
@@ -84,7 +89,7 @@ const User = RestModel.extend({
@computed("username", "name")
displayName(username, name) {
- if (Discourse.SiteSettings.enable_names && !Ember.isEmpty(name)) {
+ if (Discourse.SiteSettings.enable_names && !isEmpty(name)) {
return name;
}
return username;
@@ -92,10 +97,7 @@ const User = RestModel.extend({
@computed("profile_background_upload_url")
profileBackgroundUrl(bgUrl) {
- if (
- Ember.isEmpty(bgUrl) ||
- !Discourse.SiteSettings.allow_profile_backgrounds
- ) {
+ if (isEmpty(bgUrl) || !Discourse.SiteSettings.allow_profile_backgrounds) {
return "".htmlSafe();
}
return (
@@ -116,7 +118,7 @@ const User = RestModel.extend({
const keys = this.user_api_keys;
if (keys) {
return keys.map(raw => {
- let obj = Ember.Object.create(raw);
+ let obj = EmberObject.create(raw);
obj.revoke = () => {
this.revokeApiKey(obj);
@@ -203,10 +205,10 @@ const User = RestModel.extend({
);
},
- isBasic: Ember.computed.equal("trust_level", 0),
- isLeader: Ember.computed.equal("trust_level", 3),
- isElder: Ember.computed.equal("trust_level", 4),
- canManageTopic: Ember.computed.or("staff", "isElder"),
+ isBasic: equal("trust_level", 0),
+ isLeader: equal("trust_level", 3),
+ isElder: equal("trust_level", 4),
+ canManageTopic: or("staff", "isElder"),
@computed("previous_visit_at")
previousVisitAt(previous_visit_at) {
@@ -266,7 +268,8 @@ const User = RestModel.extend({
"tracked_tags",
"watched_tags",
"watching_first_post_tags",
- "date_of_birth"
+ "date_of_birth",
+ "primary_group_id"
];
const data = this.getProperties(
@@ -349,7 +352,7 @@ const User = RestModel.extend({
})
.then(result => {
this.set("bio_excerpt", result.user.bio_excerpt);
- const userProps = Ember.getProperties(
+ const userProps = getProperties(
this.user_option,
"enable_quoting",
"enable_defer",
@@ -512,7 +515,7 @@ const User = RestModel.extend({
// The user's stat count, excluding PMs.
@computed("statsExcludingPms.@each.count")
statsCountNonPM() {
- if (Ember.isEmpty(this.statsExcludingPms)) return 0;
+ if (isEmpty(this.statsExcludingPms)) return 0;
let count = 0;
this.statsExcludingPms.forEach(val => {
if (this.inAllStream(val)) {
@@ -525,7 +528,7 @@ const User = RestModel.extend({
// The user's stats, excluding PMs.
@computed("stats.@each.isPM")
statsExcludingPms() {
- if (Ember.isEmpty(this.stats)) return [];
+ if (isEmpty(this.stats)) return [];
return this.stats.rejectBy("isPM");
},
@@ -535,7 +538,7 @@ const User = RestModel.extend({
return PreloadStore.getAndRemove(`user_${user.get("username")}`, () => {
return ajax(userPath(`${user.get("username")}.json`), { data: options });
}).then(json => {
- if (!Ember.isEmpty(json.user.stats)) {
+ if (!isEmpty(json.user.stats)) {
json.user.stats = Discourse.User.groupStats(
json.user.stats.map(s => {
if (s.count) s.count = parseInt(s.count, 10);
@@ -544,7 +547,7 @@ const User = RestModel.extend({
);
}
- if (!Ember.isEmpty(json.user.groups)) {
+ if (!isEmpty(json.user.groups)) {
const groups = [];
for (let i = 0; i < json.user.groups.length; i++) {
@@ -560,7 +563,7 @@ const User = RestModel.extend({
json.user.invited_by = Discourse.User.create(json.user.invited_by);
}
- if (!Ember.isEmpty(json.user.featured_user_badge_ids)) {
+ if (!isEmpty(json.user.featured_user_badge_ids)) {
const userBadgesMap = {};
UserBadge.createFromJson(json).forEach(userBadge => {
userBadgesMap[userBadge.get("id")] = userBadge;
@@ -581,7 +584,7 @@ const User = RestModel.extend({
findStaffInfo() {
if (!Discourse.User.currentProp("staff")) {
- return Ember.RSVP.resolve(null);
+ return Promise.resolve(null);
}
return ajax(userPath(`${this.username_lower}/staff-info.json`)).then(
info => {
@@ -670,7 +673,7 @@ const User = RestModel.extend({
data: { context: window.location.pathname }
});
} else {
- return Ember.RSVP.reject(I18n.t("user.delete_yourself_not_allowed"));
+ return Promise.reject(I18n.t("user.delete_yourself_not_allowed"));
}
},
diff --git a/app/assets/javascripts/discourse/pre-initializers/dynamic-route-builders.js.es6 b/app/assets/javascripts/discourse/pre-initializers/dynamic-route-builders.js.es6
index a8de4fc07d..55f4fee1d9 100644
--- a/app/assets/javascripts/discourse/pre-initializers/dynamic-route-builders.js.es6
+++ b/app/assets/javascripts/discourse/pre-initializers/dynamic-route-builders.js.es6
@@ -95,6 +95,9 @@ export default {
});
app["TagsShowCategoryRoute"] = TagsShowRoute.extend();
+ app["TagsShowCategoryNoneRoute"] = TagsShowRoute.extend({
+ noSubcategories: true
+ });
app["TagsShowParentCategoryRoute"] = TagsShowRoute.extend();
site.get("filters").forEach(function(filter) {
@@ -104,6 +107,9 @@ export default {
app[
"TagsShowCategory" + filter.capitalize() + "Route"
] = TagsShowRoute.extend({ navMode: filter });
+ app[
+ "TagsShowNoneCategory" + filter.capitalize() + "Route"
+ ] = TagsShowRoute.extend({ navMode: filter, noSubcategories: true });
app[
"TagsShowParentCategory" + filter.capitalize() + "Route"
] = TagsShowRoute.extend({ navMode: filter });
diff --git a/app/assets/javascripts/discourse/raw-views/list/post-count-or-badges.js.es6 b/app/assets/javascripts/discourse/raw-views/list/post-count-or-badges.js.es6
index 2f3dc5beb9..d7c5f0aa06 100644
--- a/app/assets/javascripts/discourse/raw-views/list/post-count-or-badges.js.es6
+++ b/app/assets/javascripts/discourse/raw-views/list/post-count-or-badges.js.es6
@@ -1,8 +1,10 @@
+import { or, and } from "@ember/object/computed";
+import EmberObject from "@ember/object";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Object.extend({
- postCountsPresent: Ember.computed.or("topic.unread", "topic.displayNewPosts"),
- showBadges: Ember.computed.and("postBadgesEnabled", "postCountsPresent"),
+export default EmberObject.extend({
+ postCountsPresent: or("topic.unread", "topic.displayNewPosts"),
+ showBadges: and("postBadgesEnabled", "postCountsPresent"),
@computed
newDotText() {
diff --git a/app/assets/javascripts/discourse/raw-views/list/posts-count-column.js.es6 b/app/assets/javascripts/discourse/raw-views/list/posts-count-column.js.es6
index 2171251840..2c7ca4c9b9 100644
--- a/app/assets/javascripts/discourse/raw-views/list/posts-count-column.js.es6
+++ b/app/assets/javascripts/discourse/raw-views/list/posts-count-column.js.es6
@@ -1,7 +1,8 @@
+import EmberObject from "@ember/object";
import computed from "ember-addons/ember-computed-decorators";
import { fmt } from "discourse/lib/computed";
-export default Ember.Object.extend({
+export default EmberObject.extend({
tagName: "td",
@computed("topic.like_count", "topic.posts_count")
diff --git a/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6 b/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6
index 3626b17cb7..b2aac57550 100644
--- a/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6
+++ b/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6
@@ -1,6 +1,7 @@
+import EmberObject from "@ember/object";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Object.extend({
+export default EmberObject.extend({
@computed
isLastVisited: function() {
return this.lastVisitedTopic === this.topic;
diff --git a/app/assets/javascripts/discourse/raw-views/topic-list-header-column.js.es6 b/app/assets/javascripts/discourse/raw-views/topic-list-header-column.js.es6
index 5febdd4fef..0ac85216b7 100644
--- a/app/assets/javascripts/discourse/raw-views/topic-list-header-column.js.es6
+++ b/app/assets/javascripts/discourse/raw-views/topic-list-header-column.js.es6
@@ -1,6 +1,7 @@
+import EmberObject from "@ember/object";
import { default as computed } from "ember-addons/ember-computed-decorators";
-export default Ember.Object.extend({
+export default EmberObject.extend({
@computed
localizedName() {
if (this.forceName) {
diff --git a/app/assets/javascripts/discourse/raw-views/topic-status.js.es6 b/app/assets/javascripts/discourse/raw-views/topic-status.js.es6
index ec33498520..8e7269bbca 100644
--- a/app/assets/javascripts/discourse/raw-views/topic-status.js.es6
+++ b/app/assets/javascripts/discourse/raw-views/topic-status.js.es6
@@ -1,6 +1,7 @@
+import EmberObject from "@ember/object";
import computed from "ember-addons/ember-computed-decorators";
-export default Ember.Object.extend({
+export default EmberObject.extend({
showDefault: null,
@computed("defaultIcon")
diff --git a/app/assets/javascripts/discourse/routes/about.js.es6 b/app/assets/javascripts/discourse/routes/about.js.es6
index 3b19492a6b..f7d88a8421 100644
--- a/app/assets/javascripts/discourse/routes/about.js.es6
+++ b/app/assets/javascripts/discourse/routes/about.js.es6
@@ -1,5 +1,7 @@
import { ajax } from "discourse/lib/ajax";
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
return ajax("/about.json").then(result => {
let activeAdmins = [];
diff --git a/app/assets/javascripts/discourse/routes/account-created-edit-email.js.es6 b/app/assets/javascripts/discourse/routes/account-created-edit-email.js.es6
index 0922f7fe09..0946fe05db 100644
--- a/app/assets/javascripts/discourse/routes/account-created-edit-email.js.es6
+++ b/app/assets/javascripts/discourse/routes/account-created-edit-email.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
setupController(controller) {
const accountCreated = this.controllerFor("account-created").get(
"accountCreated"
diff --git a/app/assets/javascripts/discourse/routes/account-created-index.js.es6 b/app/assets/javascripts/discourse/routes/account-created-index.js.es6
index 33aa658049..d3f46333a6 100644
--- a/app/assets/javascripts/discourse/routes/account-created-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/account-created-index.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
setupController(controller) {
controller.set(
"accountCreated",
diff --git a/app/assets/javascripts/discourse/routes/account-created-resent.js.es6 b/app/assets/javascripts/discourse/routes/account-created-resent.js.es6
index deb2af1970..047906d262 100644
--- a/app/assets/javascripts/discourse/routes/account-created-resent.js.es6
+++ b/app/assets/javascripts/discourse/routes/account-created-resent.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
setupController(controller) {
controller.set(
"email",
diff --git a/app/assets/javascripts/discourse/routes/account-created.js.es6 b/app/assets/javascripts/discourse/routes/account-created.js.es6
index ab117f5988..901f6c0ffb 100644
--- a/app/assets/javascripts/discourse/routes/account-created.js.es6
+++ b/app/assets/javascripts/discourse/routes/account-created.js.es6
@@ -1,6 +1,7 @@
+import Route from "@ember/routing/route";
import PreloadStore from "preload-store";
-export default Ember.Route.extend({
+export default Route.extend({
setupController(controller) {
controller.set("accountCreated", PreloadStore.get("accountCreated"));
}
diff --git a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 b/app/assets/javascripts/discourse/routes/app-route-map.js.es6
index 654c683a45..1da84b4047 100644
--- a/app/assets/javascripts/discourse/routes/app-route-map.js.es6
+++ b/app/assets/javascripts/discourse/routes/app-route-map.js.es6
@@ -156,7 +156,6 @@ export default function() {
this.route("email");
this.route("second-factor");
this.route("second-factor-backup");
- this.route("about", { path: "/about-me" });
});
this.route(
@@ -200,6 +199,7 @@ export default function() {
this.route("tags", { resetNamespace: true }, function() {
this.route("show", { path: "/:tag_id" });
this.route("showCategory", { path: "/c/:category/:tag_id" });
+ this.route("showCategoryNone", { path: "/c/:category/none/:tag_id" });
this.route("showParentCategory", {
path: "/c/:parent_category/:category/:tag_id"
});
@@ -211,6 +211,9 @@ export default function() {
this.route("showCategory" + filter.capitalize(), {
path: "/c/:category/:tag_id/l/" + filter
});
+ this.route("showCategoryNone" + filter.capitalize(), {
+ path: "/c/:category/:tag_id/l/" + filter
+ });
this.route("showParentCategory" + filter.capitalize(), {
path: "/c/:parent_category/:category/:tag_id/l/" + filter
});
@@ -224,7 +227,8 @@ export default function() {
"tagGroups",
{ path: "/tag_groups", resetNamespace: true },
function() {
- this.route("show", { path: "/:id" });
+ this.route("edit", { path: "/:id" });
+ this.route("new");
}
);
diff --git a/app/assets/javascripts/discourse/routes/application.js.es6 b/app/assets/javascripts/discourse/routes/application.js.es6
index 4c85a42862..cb1e5f0406 100644
--- a/app/assets/javascripts/discourse/routes/application.js.es6
+++ b/app/assets/javascripts/discourse/routes/application.js.es6
@@ -1,3 +1,6 @@
+import { once } from "@ember/runloop";
+import { next } from "@ember/runloop";
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { setting } from "discourse/lib/computed";
import logout from "discourse/lib/logout";
@@ -20,7 +23,7 @@ function unlessReadOnly(method, message) {
};
}
-const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
+const ApplicationRoute = DiscourseRoute.extend(OpenComposer, {
siteTitle: setting("title"),
shortSiteDescription: setting("short_site_description"),
@@ -43,7 +46,8 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
_collectTitleTokens(tokens) {
tokens.push(this.siteTitle);
if (
- window.location.pathname === Discourse.getURL("/") &&
+ (window.location.pathname === Discourse.getURL("/") ||
+ window.location.pathname === Discourse.getURL("/login")) &&
this.shortSiteDescription !== ""
) {
tokens.push(this.shortSiteDescription);
@@ -54,7 +58,7 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
// Ember doesn't provider a router `willTransition` event so let's make one
willTransition() {
var router = getOwner(this).lookup("router:main");
- Ember.run.once(router, router.trigger, "willTransition");
+ once(router, router.trigger, "willTransition");
return this._super(...arguments);
},
@@ -81,7 +85,7 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
action: Composer.PRIVATE_MESSAGE,
usernames: recipient,
archetypeId: "private_message",
- draftKey: "new_private_message",
+ draftKey: Composer.NEW_PRIVATE_MESSAGE_KEY,
reply,
title
});
@@ -224,7 +228,7 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
activate() {
this._super(...arguments);
- Ember.run.next(function() {
+ next(function() {
// Support for callbacks once the application has activated
ApplicationRoute.trigger("activate");
});
diff --git a/app/assets/javascripts/discourse/routes/associate-account.js.es6 b/app/assets/javascripts/discourse/routes/associate-account.js.es6
index d89654e078..a182e85c88 100644
--- a/app/assets/javascripts/discourse/routes/associate-account.js.es6
+++ b/app/assets/javascripts/discourse/routes/associate-account.js.es6
@@ -1,12 +1,14 @@
+import { next } from "@ember/runloop";
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import showModal from "discourse/lib/show-modal";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
beforeModel() {
const params = this.paramsFor("associate-account");
this.replaceWith(`preferences.account`, this.currentUser).then(() =>
- Ember.run.next(() =>
+ next(() =>
ajax(`/associate/${encodeURIComponent(params.token)}.json`)
.then(model => showModal("associate-account-confirm", { model }))
.catch(popupAjaxError)
diff --git a/app/assets/javascripts/discourse/routes/badges-index.js.es6 b/app/assets/javascripts/discourse/routes/badges-index.js.es6
index 2df72ea584..c4acb15592 100644
--- a/app/assets/javascripts/discourse/routes/badges-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/badges-index.js.es6
@@ -1,7 +1,8 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Badge from "discourse/models/badge";
import PreloadStore from "preload-store";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
if (PreloadStore.get("badges")) {
return PreloadStore.getAndRemove("badges").then(json =>
diff --git a/app/assets/javascripts/discourse/routes/badges-show.js.es6 b/app/assets/javascripts/discourse/routes/badges-show.js.es6
index 3507beac99..86b8f0d4af 100644
--- a/app/assets/javascripts/discourse/routes/badges-show.js.es6
+++ b/app/assets/javascripts/discourse/routes/badges-show.js.es6
@@ -1,8 +1,10 @@
+import DiscourseRoute from "discourse/routes/discourse";
import UserBadge from "discourse/models/user-badge";
import Badge from "discourse/models/badge";
import PreloadStore from "preload-store";
+import { hash } from "rsvp";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
queryParams: {
username: {
refreshModel: true
@@ -51,7 +53,7 @@ export default Discourse.Route.extend({
userBadgesAll
};
- return Ember.RSVP.hash(promises);
+ return hash(promises);
},
titleToken() {
diff --git a/app/assets/javascripts/discourse/routes/build-admin-user-posts-route.js.es6 b/app/assets/javascripts/discourse/routes/build-admin-user-posts-route.js.es6
index bc80113310..5bbd0108c6 100644
--- a/app/assets/javascripts/discourse/routes/build-admin-user-posts-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-admin-user-posts-route.js.es6
@@ -1,7 +1,8 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { emojiUnescape } from "discourse/lib/text";
export default function(filter) {
- return Discourse.Route.extend({
+ return DiscourseRoute.extend({
actions: {
didTransition() {
this.controllerFor("user").set("indexStream", true);
diff --git a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
index aadf72eb35..06259b920c 100644
--- a/app/assets/javascripts/discourse/routes/build-category-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
@@ -1,3 +1,4 @@
+import DiscourseRoute from "discourse/routes/discourse";
import {
filterQueryParams,
findTopicList
@@ -7,10 +8,11 @@ import TopicList from "discourse/models/topic-list";
import PermissionType from "discourse/models/permission-type";
import CategoryList from "discourse/models/category-list";
import Category from "discourse/models/category";
+import { Promise, all } from "rsvp";
// A helper function to create a category route with parameters
export default (filterArg, params) => {
- return Discourse.Route.extend({
+ return DiscourseRoute.extend({
queryParams,
model(modelParams) {
@@ -49,7 +51,7 @@ export default (filterArg, params) => {
}
this._setupNavigation(model.category);
- return Ember.RSVP.all([
+ return all([
this._createSubcategoryList(model.category),
this._retrieveTopicList(model.category, transition)
]);
@@ -86,7 +88,7 @@ export default (filterArg, params) => {
}
// If we're not loading a subcategory list just resolve
- return Ember.RSVP.resolve();
+ return Promise.resolve();
},
_retrieveTopicList(category, transition) {
diff --git a/app/assets/javascripts/discourse/routes/build-private-messages-route.js.es6 b/app/assets/javascripts/discourse/routes/build-private-messages-route.js.es6
index 4ebca3108a..7331705f8f 100644
--- a/app/assets/javascripts/discourse/routes/build-private-messages-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-private-messages-route.js.es6
@@ -1,4 +1,5 @@
import UserTopicListRoute from "discourse/routes/user-topic-list";
+import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
// A helper to build a user topic list route
export default (viewName, path, channel) => {
@@ -18,10 +19,12 @@ export default (viewName, path, channel) => {
},
model() {
- return this.store.findFiltered("topicList", {
- filter:
- "topics/" + path + "/" + this.modelFor("user").get("username_lower")
- });
+ const filter =
+ "topics/" + path + "/" + this.modelFor("user").get("username_lower");
+ const lastTopicList = findOrResetCachedTopicList(this.session, filter);
+ return lastTopicList
+ ? lastTopicList
+ : this.store.findFiltered("topicList", { filter });
},
setupController() {
diff --git a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6 b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
index 72db37455b..5d0a576005 100644
--- a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
@@ -1,9 +1,11 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { queryParams } from "discourse/controllers/discovery-sortable";
import { defaultHomepage } from "discourse/lib/utilities";
// A helper to build a topic route for a filter
function filterQueryParams(params, defaultParams) {
- const findOpts = defaultParams || {};
+ const findOpts = Object.assign({}, defaultParams || {});
+
if (params) {
Object.keys(queryParams).forEach(function(opt) {
if (params[opt]) {
@@ -16,7 +18,7 @@ function filterQueryParams(params, defaultParams) {
function findTopicList(store, tracking, filter, filterParams, extras) {
extras = extras || {};
- return new Ember.RSVP.Promise(function(resolve) {
+ return new Promise(function(resolve) {
const session = Discourse.Session.current();
if (extras.cached) {
@@ -70,7 +72,7 @@ function findTopicList(store, tracking, filter, filterParams, extras) {
export default function(filter, extras) {
extras = extras || {};
- return Discourse.Route.extend(
+ return DiscourseRoute.extend(
{
queryParams,
diff --git a/app/assets/javascripts/discourse/routes/discourse.js.es6 b/app/assets/javascripts/discourse/routes/discourse.js.es6
index 51bdcbbc2b..2329168593 100644
--- a/app/assets/javascripts/discourse/routes/discourse.js.es6
+++ b/app/assets/javascripts/discourse/routes/discourse.js.es6
@@ -1,7 +1,9 @@
+import { once } from "@ember/runloop";
import Composer from "discourse/models/composer";
import { getOwner } from "discourse-common/lib/get-owner";
+import Route from "@ember/routing/route";
-const DiscourseRoute = Ember.Route.extend({
+const DiscourseRoute = Route.extend({
showFooter: false,
// Set to true to refresh a model without a transition if a query param
@@ -54,7 +56,7 @@ const DiscourseRoute = Ember.Route.extend({
},
refreshTitle() {
- Ember.run.once(this, this._refreshTitleOnce);
+ once(this, this._refreshTitleOnce);
},
clearTopicDraft() {
diff --git a/app/assets/javascripts/discourse/routes/discovery-categories.js.es6 b/app/assets/javascripts/discourse/routes/discovery-categories.js.es6
index 49605dd6c3..f5bafdf12b 100644
--- a/app/assets/javascripts/discourse/routes/discovery-categories.js.es6
+++ b/app/assets/javascripts/discourse/routes/discovery-categories.js.es6
@@ -1,3 +1,6 @@
+import EmberObject from "@ember/object";
+import { next } from "@ember/runloop";
+import DiscourseRoute from "discourse/routes/discourse";
import showModal from "discourse/lib/show-modal";
import OpenComposer from "discourse/mixins/open-composer";
import CategoryList from "discourse/models/category-list";
@@ -6,8 +9,9 @@ import TopicList from "discourse/models/topic-list";
import { ajax } from "discourse/lib/ajax";
import PreloadStore from "preload-store";
import { searchPriorities } from "discourse/components/concerns/category-search-priorities";
+import { hash } from "rsvp";
-const DiscoveryCategoriesRoute = Discourse.Route.extend(OpenComposer, {
+const DiscoveryCategoriesRoute = DiscourseRoute.extend(OpenComposer, {
renderTemplate() {
this.render("navigation/categories", { outlet: "navigation-bar" });
this.render("discovery/categories", { outlet: "list-container" });
@@ -41,16 +45,16 @@ const DiscoveryCategoriesRoute = Discourse.Route.extend(OpenComposer, {
},
_findCategoriesAndTopics(filter) {
- return Ember.RSVP.hash({
+ return hash({
wrappedCategoriesList: PreloadStore.getAndRemove("categories_list"),
topicsList: PreloadStore.getAndRemove(`topic_list_${filter}`)
- }).then(hash => {
- let { wrappedCategoriesList, topicsList } = hash;
+ }).then(response => {
+ let { wrappedCategoriesList, topicsList } = response;
let categoriesList =
wrappedCategoriesList && wrappedCategoriesList.category_list;
if (categoriesList && topicsList) {
- return Ember.Object.create({
+ return EmberObject.create({
categories: CategoryList.categoriesFrom(
this.store,
wrappedCategoriesList
@@ -65,7 +69,7 @@ const DiscoveryCategoriesRoute = Discourse.Route.extend(OpenComposer, {
}
// Otherwise, return the ajax result
return ajax(`/categories_and_${filter}`).then(result => {
- return Ember.Object.create({
+ return EmberObject.create({
categories: CategoryList.categoriesFrom(this.store, result),
topics: TopicList.topicsFrom(this.store, result),
can_create_category: result.category_list.can_create_category,
@@ -132,9 +136,7 @@ const DiscoveryCategoriesRoute = Discourse.Route.extend(OpenComposer, {
},
didTransition() {
- Ember.run.next(() =>
- this.controllerFor("application").set("showFooter", true)
- );
+ next(() => this.controllerFor("application").set("showFooter", true));
return true;
}
}
diff --git a/app/assets/javascripts/discourse/routes/discovery.js.es6 b/app/assets/javascripts/discourse/routes/discovery.js.es6
index 234ef15930..68796918ef 100644
--- a/app/assets/javascripts/discourse/routes/discovery.js.es6
+++ b/app/assets/javascripts/discourse/routes/discovery.js.es6
@@ -2,10 +2,11 @@
The parent route for all discovery routes.
Handles the logic for showing the loading spinners.
**/
+import DiscourseRoute from "discourse/routes/discourse";
import OpenComposer from "discourse/mixins/open-composer";
import { scrollTop } from "discourse/mixins/scroll-top";
-export default Discourse.Route.extend(OpenComposer, {
+export default DiscourseRoute.extend(OpenComposer, {
redirect() {
return this.redirectIfLoginRequired();
},
diff --git a/app/assets/javascripts/discourse/routes/email-login.js.es6 b/app/assets/javascripts/discourse/routes/email-login.js.es6
index 617de051cd..642d5ee3d6 100644
--- a/app/assets/javascripts/discourse/routes/email-login.js.es6
+++ b/app/assets/javascripts/discourse/routes/email-login.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("login.title");
},
diff --git a/app/assets/javascripts/discourse/routes/exception.js.es6 b/app/assets/javascripts/discourse/routes/exception.js.es6
index 1b64efb9a6..d90cd0fb76 100644
--- a/app/assets/javascripts/discourse/routes/exception.js.es6
+++ b/app/assets/javascripts/discourse/routes/exception.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
serialize() {
return "";
},
diff --git a/app/assets/javascripts/discourse/routes/forgot-password.js.es6 b/app/assets/javascripts/discourse/routes/forgot-password.js.es6
index e88fbdb082..58309565b5 100644
--- a/app/assets/javascripts/discourse/routes/forgot-password.js.es6
+++ b/app/assets/javascripts/discourse/routes/forgot-password.js.es6
@@ -1,3 +1,4 @@
+import { next } from "@ember/runloop";
import { defaultHomepage } from "discourse/lib/utilities";
import buildStaticRoute from "discourse/routes/build-static-route";
@@ -11,7 +12,7 @@ ForgotPasswordRoute.reopen({
this.replaceWith(
loginRequired ? "login" : `discovery.${defaultHomepage()}`
).then(e => {
- Ember.run.next(() => e.send("showForgotPassword"));
+ next(() => e.send("showForgotPassword"));
});
}
});
diff --git a/app/assets/javascripts/discourse/routes/full-page-search.js.es6 b/app/assets/javascripts/discourse/routes/full-page-search.js.es6
index 97ec4772e7..ca7906e109 100644
--- a/app/assets/javascripts/discourse/routes/full-page-search.js.es6
+++ b/app/assets/javascripts/discourse/routes/full-page-search.js.es6
@@ -1,3 +1,4 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import {
translateResults,
@@ -8,7 +9,7 @@ import PreloadStore from "preload-store";
import { getTransient, setTransient } from "discourse/lib/page-tracker";
import { escapeExpression } from "discourse/lib/utilities";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
queryParams: {
q: {},
expanded: false,
diff --git a/app/assets/javascripts/discourse/routes/group-activity-index.js.es6 b/app/assets/javascripts/discourse/routes/group-activity-index.js.es6
index 4ad23d5f64..de7b551a80 100644
--- a/app/assets/javascripts/discourse/routes/group-activity-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-activity-index.js.es6
@@ -1,4 +1,6 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+
+export default Route.extend({
beforeModel() {
const group = this.modelFor("group");
if (group.can_see_members) {
diff --git a/app/assets/javascripts/discourse/routes/group-activity-posts.js.es6 b/app/assets/javascripts/discourse/routes/group-activity-posts.js.es6
index 62aad28945..86b35b6534 100644
--- a/app/assets/javascripts/discourse/routes/group-activity-posts.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-activity-posts.js.es6
@@ -1,5 +1,8 @@
+import { get } from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
+
export function buildGroupPage(type) {
- return Discourse.Route.extend({
+ return DiscourseRoute.extend({
type,
titleToken() {
@@ -7,7 +10,7 @@ export function buildGroupPage(type) {
},
model(params, transition) {
- let categoryId = Ember.get(transition.to, "queryParams.category_id");
+ let categoryId = get(transition.to, "queryParams.category_id");
return this.modelFor("group").findPosts({ type, categoryId });
},
diff --git a/app/assets/javascripts/discourse/routes/group-activity-topics.js.es6 b/app/assets/javascripts/discourse/routes/group-activity-topics.js.es6
index a36ec0e6e5..b1b77f40b7 100644
--- a/app/assets/javascripts/discourse/routes/group-activity-topics.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-activity-topics.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t(`groups.topics`);
},
diff --git a/app/assets/javascripts/discourse/routes/group-index.js.es6 b/app/assets/javascripts/discourse/routes/group-index.js.es6
index 2aab4410ab..a8f630df0f 100644
--- a/app/assets/javascripts/discourse/routes/group-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-index.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import showModal from "discourse/lib/show-modal";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("groups.members.title");
},
diff --git a/app/assets/javascripts/discourse/routes/group-manage-index.js.es6 b/app/assets/javascripts/discourse/routes/group-manage-index.js.es6
index 590722bb0f..4e9cf5c71c 100644
--- a/app/assets/javascripts/discourse/routes/group-manage-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-manage-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
showFooter: true,
beforeModel() {
diff --git a/app/assets/javascripts/discourse/routes/group-manage-interaction.js.es6 b/app/assets/javascripts/discourse/routes/group-manage-interaction.js.es6
index e8f3be3da2..e273e2d22f 100644
--- a/app/assets/javascripts/discourse/routes/group-manage-interaction.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-manage-interaction.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
showFooter: true,
titleToken() {
diff --git a/app/assets/javascripts/discourse/routes/group-manage-logs.js.es6 b/app/assets/javascripts/discourse/routes/group-manage-logs.js.es6
index 56b092ecfe..ad49c84619 100644
--- a/app/assets/javascripts/discourse/routes/group-manage-logs.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-manage-logs.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("groups.manage.logs.title");
},
diff --git a/app/assets/javascripts/discourse/routes/group-manage-membership.js.es6 b/app/assets/javascripts/discourse/routes/group-manage-membership.js.es6
index 37746f3e91..1ded3e2b07 100644
--- a/app/assets/javascripts/discourse/routes/group-manage-membership.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-manage-membership.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
showFooter: true,
titleToken() {
diff --git a/app/assets/javascripts/discourse/routes/group-manage-profile.js.es6 b/app/assets/javascripts/discourse/routes/group-manage-profile.js.es6
index e0f133e0ce..b720151ff4 100644
--- a/app/assets/javascripts/discourse/routes/group-manage-profile.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-manage-profile.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
showFooter: true,
titleToken() {
diff --git a/app/assets/javascripts/discourse/routes/group-manage.js.es6 b/app/assets/javascripts/discourse/routes/group-manage.js.es6
index 54122bcbd4..70b5f053c7 100644
--- a/app/assets/javascripts/discourse/routes/group-manage.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-manage.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
showFooter: true,
titleToken() {
diff --git a/app/assets/javascripts/discourse/routes/group-members.js.es6 b/app/assets/javascripts/discourse/routes/group-members.js.es6
index 8ec71ae22a..872052de67 100644
--- a/app/assets/javascripts/discourse/routes/group-members.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-members.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
beforeModel: function() {
this.transitionTo("group.index");
}
diff --git a/app/assets/javascripts/discourse/routes/group-messages-index.js.es6 b/app/assets/javascripts/discourse/routes/group-messages-index.js.es6
index 68750d154a..be802450b2 100644
--- a/app/assets/javascripts/discourse/routes/group-messages-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-messages-index.js.es6
@@ -1,4 +1,5 @@
-export default Ember.Route.extend({
+import Route from "@ember/routing/route";
+export default Route.extend({
beforeModel: function() {
this.transitionTo("group.messages.inbox");
}
diff --git a/app/assets/javascripts/discourse/routes/group-messages.js.es6 b/app/assets/javascripts/discourse/routes/group-messages.js.es6
index 82f26f93e2..1a605ec168 100644
--- a/app/assets/javascripts/discourse/routes/group-messages.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-messages.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("groups.messages");
},
diff --git a/app/assets/javascripts/discourse/routes/group-requests.js.es6 b/app/assets/javascripts/discourse/routes/group-requests.js.es6
index c469c9895a..b299bb01bf 100644
--- a/app/assets/javascripts/discourse/routes/group-requests.js.es6
+++ b/app/assets/javascripts/discourse/routes/group-requests.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("groups.requests.title");
},
diff --git a/app/assets/javascripts/discourse/routes/group.js.es6 b/app/assets/javascripts/discourse/routes/group.js.es6
index 9e2c7f87de..bd58f6d3a7 100644
--- a/app/assets/javascripts/discourse/routes/group.js.es6
+++ b/app/assets/javascripts/discourse/routes/group.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return [this.modelFor("group").get("name")];
},
diff --git a/app/assets/javascripts/discourse/routes/groups-index.js.es6 b/app/assets/javascripts/discourse/routes/groups-index.js.es6
index e7189d778f..a510bd93b6 100644
--- a/app/assets/javascripts/discourse/routes/groups-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/groups-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("groups.index.title");
},
diff --git a/app/assets/javascripts/discourse/routes/groups-new.js.es6 b/app/assets/javascripts/discourse/routes/groups-new.js.es6
index 8c2bbd29a7..67f76347d9 100644
--- a/app/assets/javascripts/discourse/routes/groups-new.js.es6
+++ b/app/assets/javascripts/discourse/routes/groups-new.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Group from "discourse/models/group";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
showFooter: true,
titleToken() {
diff --git a/app/assets/javascripts/discourse/routes/invites-show.js.es6 b/app/assets/javascripts/discourse/routes/invites-show.js.es6
index 93f4bdcc40..7ec701b842 100644
--- a/app/assets/javascripts/discourse/routes/invites-show.js.es6
+++ b/app/assets/javascripts/discourse/routes/invites-show.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import PreloadStore from "preload-store";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("invites.accept_title");
},
diff --git a/app/assets/javascripts/discourse/routes/login.js.es6 b/app/assets/javascripts/discourse/routes/login.js.es6
index 8465ceb6bc..c41f884f30 100644
--- a/app/assets/javascripts/discourse/routes/login.js.es6
+++ b/app/assets/javascripts/discourse/routes/login.js.es6
@@ -1,3 +1,4 @@
+import { next } from "@ember/runloop";
import buildStaticRoute from "discourse/routes/build-static-route";
import { defaultHomepage } from "discourse/lib/utilities";
@@ -7,7 +8,7 @@ LoginRoute.reopen({
beforeModel() {
if (!this.siteSettings.login_required) {
this.replaceWith(`/${defaultHomepage()}`).then(e => {
- Ember.run.next(() => e.send("showLogin"));
+ next(() => e.send("showLogin"));
});
}
}
diff --git a/app/assets/javascripts/discourse/routes/new-message.js.es6 b/app/assets/javascripts/discourse/routes/new-message.js.es6
index 42b664fde5..c85001cbbf 100644
--- a/app/assets/javascripts/discourse/routes/new-message.js.es6
+++ b/app/assets/javascripts/discourse/routes/new-message.js.es6
@@ -1,7 +1,9 @@
+import { next } from "@ember/runloop";
+import DiscourseRoute from "discourse/routes/discourse";
import User from "discourse/models/user";
import Group from "discourse/models/group";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
beforeModel(transition) {
const params = transition.to.queryParams;
@@ -14,7 +16,7 @@ export default Discourse.Route.extend({
User.findByUsername(encodeURIComponent(params.username))
.then(user => {
if (user.can_send_private_message_to_user) {
- Ember.run.next(() =>
+ next(() =>
e.send(
"createNewMessageViaParams",
user.username,
@@ -34,7 +36,7 @@ export default Discourse.Route.extend({
Group.messageable(groupName)
.then(result => {
if (result.messageable) {
- Ember.run.next(() =>
+ next(() =>
e.send(
"createNewMessageViaParams",
groupName,
diff --git a/app/assets/javascripts/discourse/routes/new-topic.js.es6 b/app/assets/javascripts/discourse/routes/new-topic.js.es6
index 266276fd06..550b4b5341 100644
--- a/app/assets/javascripts/discourse/routes/new-topic.js.es6
+++ b/app/assets/javascripts/discourse/routes/new-topic.js.es6
@@ -1,6 +1,8 @@
+import { next } from "@ember/runloop";
+import DiscourseRoute from "discourse/routes/discourse";
import Category from "discourse/models/category";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
beforeModel(transition) {
if (this.currentUser) {
let category, categoryId;
@@ -62,7 +64,7 @@ export default Discourse.Route.extend({
},
_sendTransition(event, transition, categoryId) {
- Ember.run.next(() => {
+ next(() => {
event.send(
"createNewTopicViaParams",
transition.to.queryParams.title,
diff --git a/app/assets/javascripts/discourse/routes/password-reset.js.es6 b/app/assets/javascripts/discourse/routes/password-reset.js.es6
index a0ccc31484..393b19f96a 100644
--- a/app/assets/javascripts/discourse/routes/password-reset.js.es6
+++ b/app/assets/javascripts/discourse/routes/password-reset.js.es6
@@ -1,8 +1,9 @@
+import DiscourseRoute from "discourse/routes/discourse";
import PreloadStore from "preload-store";
import { ajax } from "discourse/lib/ajax";
import { userPath } from "discourse/lib/url";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("login.reset_password");
},
diff --git a/app/assets/javascripts/discourse/routes/post.js.es6 b/app/assets/javascripts/discourse/routes/post.js.es6
index c63a71243c..15b8aa3d1a 100644
--- a/app/assets/javascripts/discourse/routes/post.js.es6
+++ b/app/assets/javascripts/discourse/routes/post.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
beforeModel({ params }) {
return ajax(`/p/${params.post.id}`).then(t => {
this.transitionTo(
diff --git a/app/assets/javascripts/discourse/routes/preferences-about.js.es6 b/app/assets/javascripts/discourse/routes/preferences-about.js.es6
deleted file mode 100644
index d6e29ec781..0000000000
--- a/app/assets/javascripts/discourse/routes/preferences-about.js.es6
+++ /dev/null
@@ -1,46 +0,0 @@
-import RestrictedUserRoute from "discourse/routes/restricted-user";
-
-export default RestrictedUserRoute.extend({
- showFooter: true,
-
- model: function() {
- return this.modelFor("user");
- },
-
- renderTemplate: function() {
- this.render({ into: "user" });
- },
-
- setupController: function(controller, model) {
- controller.setProperties({ model, newBio: model.get("bio_raw") });
- },
-
- // A bit odd, but if we leave to /preferences we need to re-render that outlet
- deactivate: function() {
- this._super(...arguments);
- this.render("preferences", { into: "user", controller: "preferences" });
- },
-
- actions: {
- changeAbout: function() {
- var route = this;
- var controller = route.controllerFor("preferences/about");
-
- controller.setProperties({ saving: true });
- return controller
- .get("model")
- .save()
- .then(
- function() {
- controller.set("saving", false);
- route.transitionTo("user.index");
- },
- function() {
- // model failed to save
- controller.set("saving", false);
- bootbox.alert(I18n.t("generic_error"));
- }
- );
- }
- }
-});
diff --git a/app/assets/javascripts/discourse/routes/preferences-account.js.es6 b/app/assets/javascripts/discourse/routes/preferences-account.js.es6
index e654ff0622..6ea1e95b95 100644
--- a/app/assets/javascripts/discourse/routes/preferences-account.js.es6
+++ b/app/assets/javascripts/discourse/routes/preferences-account.js.es6
@@ -21,7 +21,8 @@ export default RestrictedUserRoute.extend({
controller.setProperties({
model: user,
newNameInput: user.get("name"),
- newTitleInput: user.get("title")
+ newTitleInput: user.get("title"),
+ newPrimaryGroupInput: user.get("primary_group_id")
});
},
diff --git a/app/assets/javascripts/discourse/routes/preferences-second-factor.js.es6 b/app/assets/javascripts/discourse/routes/preferences-second-factor.js.es6
index 763460bc23..cae63a6707 100644
--- a/app/assets/javascripts/discourse/routes/preferences-second-factor.js.es6
+++ b/app/assets/javascripts/discourse/routes/preferences-second-factor.js.es6
@@ -45,7 +45,7 @@ export default RestrictedUserRoute.extend({
if (
transition.targetName === "preferences.second-factor" ||
!user ||
- (settings.allow_anonymous_posting && user.is_anonymous) ||
+ user.is_anonymous ||
user.second_factor_enabled ||
(settings.enforce_second_factor === "staff" && !user.staff) ||
settings.enforce_second_factor === "no"
diff --git a/app/assets/javascripts/discourse/routes/review-index.js.es6 b/app/assets/javascripts/discourse/routes/review-index.js.es6
index b6ba62ab45..d5b2fad370 100644
--- a/app/assets/javascripts/discourse/routes/review-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/review-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model(params) {
return this.store.findAll("reviewable", params);
},
diff --git a/app/assets/javascripts/discourse/routes/review-settings.js.es6 b/app/assets/javascripts/discourse/routes/review-settings.js.es6
index 46ed6f10fa..bb5e2e5fb1 100644
--- a/app/assets/javascripts/discourse/routes/review-settings.js.es6
+++ b/app/assets/javascripts/discourse/routes/review-settings.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
return this.store.find("reviewable-settings");
},
diff --git a/app/assets/javascripts/discourse/routes/review-show.js.es6 b/app/assets/javascripts/discourse/routes/review-show.js.es6
index afe7b30a5d..2d6d9795d4 100644
--- a/app/assets/javascripts/discourse/routes/review-show.js.es6
+++ b/app/assets/javascripts/discourse/routes/review-show.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
setupController(controller, model) {
controller.set("reviewable", model);
}
diff --git a/app/assets/javascripts/discourse/routes/review-topics.js.es6 b/app/assets/javascripts/discourse/routes/review-topics.js.es6
index 7c3f058fbd..262194ed00 100644
--- a/app/assets/javascripts/discourse/routes/review-topics.js.es6
+++ b/app/assets/javascripts/discourse/routes/review-topics.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
return this.store.findAll("reviewable-topic");
},
diff --git a/app/assets/javascripts/discourse/routes/review.js.es6 b/app/assets/javascripts/discourse/routes/review.js.es6
index 6343919dfc..9c28f22c54 100644
--- a/app/assets/javascripts/discourse/routes/review.js.es6
+++ b/app/assets/javascripts/discourse/routes/review.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
return I18n.t("review.title");
}
diff --git a/app/assets/javascripts/discourse/routes/signup.js.es6 b/app/assets/javascripts/discourse/routes/signup.js.es6
index a2753ded2b..9a732c67d8 100644
--- a/app/assets/javascripts/discourse/routes/signup.js.es6
+++ b/app/assets/javascripts/discourse/routes/signup.js.es6
@@ -1,3 +1,4 @@
+import { next } from "@ember/runloop";
import buildStaticRoute from "discourse/routes/build-static-route";
const SignupRoute = buildStaticRoute("signup");
@@ -9,13 +10,13 @@ SignupRoute.reopen({
if (!this.siteSettings.login_required) {
this.replaceWith("discovery.latest").then(e => {
if (canSignUp) {
- Ember.run.next(() => e.send("showCreateAccount"));
+ next(() => e.send("showCreateAccount"));
}
});
} else {
this.replaceWith("login").then(e => {
if (canSignUp) {
- Ember.run.next(() => e.send("showCreateAccount"));
+ next(() => e.send("showCreateAccount"));
}
});
}
diff --git a/app/assets/javascripts/discourse/routes/tag-groups-edit.js.es6 b/app/assets/javascripts/discourse/routes/tag-groups-edit.js.es6
new file mode 100644
index 0000000000..a923282cce
--- /dev/null
+++ b/app/assets/javascripts/discourse/routes/tag-groups-edit.js.es6
@@ -0,0 +1,13 @@
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
+ showFooter: true,
+
+ model(params) {
+ return this.store.find("tagGroup", params.id);
+ },
+
+ afterModel(tagGroup) {
+ tagGroup.set("savingStatus", null);
+ }
+});
diff --git a/app/assets/javascripts/discourse/routes/tag-groups-new.js.es6 b/app/assets/javascripts/discourse/routes/tag-groups-new.js.es6
new file mode 100644
index 0000000000..64c460f512
--- /dev/null
+++ b/app/assets/javascripts/discourse/routes/tag-groups-new.js.es6
@@ -0,0 +1,17 @@
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
+ showFooter: true,
+
+ beforeModel() {
+ if (!this.siteSettings.tagging_enabled) {
+ this.transitionTo("tagGroups");
+ }
+ },
+
+ model() {
+ return this.store.createRecord("tagGroup", {
+ name: I18n.t("tagging.groups.new_name")
+ });
+ }
+});
diff --git a/app/assets/javascripts/discourse/routes/tag-groups-show.js.es6 b/app/assets/javascripts/discourse/routes/tag-groups-show.js.es6
deleted file mode 100644
index 165ae49d4a..0000000000
--- a/app/assets/javascripts/discourse/routes/tag-groups-show.js.es6
+++ /dev/null
@@ -1,7 +0,0 @@
-export default Discourse.Route.extend({
- showFooter: true,
-
- model(params) {
- return this.store.find("tagGroup", params.id);
- }
-});
diff --git a/app/assets/javascripts/discourse/routes/tag-groups.js.es6 b/app/assets/javascripts/discourse/routes/tag-groups.js.es6
index ccc7d79b75..1010b04c03 100644
--- a/app/assets/javascripts/discourse/routes/tag-groups.js.es6
+++ b/app/assets/javascripts/discourse/routes/tag-groups.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
showFooter: true,
model() {
diff --git a/app/assets/javascripts/discourse/routes/tags-index.js.es6 b/app/assets/javascripts/discourse/routes/tags-index.js.es6
index c9436e876d..99cd3a211d 100644
--- a/app/assets/javascripts/discourse/routes/tags-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/tags-index.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Tag from "discourse/models/tag";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return this.store.findAll("tag").then(result => {
if (result.extras) {
diff --git a/app/assets/javascripts/discourse/routes/tags-show.js.es6 b/app/assets/javascripts/discourse/routes/tags-show.js.es6
index 3a10287935..c718cc75ff 100644
--- a/app/assets/javascripts/discourse/routes/tags-show.js.es6
+++ b/app/assets/javascripts/discourse/routes/tags-show.js.es6
@@ -1,3 +1,4 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Composer from "discourse/models/composer";
import showModal from "discourse/lib/show-modal";
import {
@@ -7,7 +8,7 @@ import {
import { queryParams } from "discourse/controllers/discovery-sortable";
import PermissionType from "discourse/models/permission-type";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
navMode: "latest",
queryParams,
@@ -84,6 +85,8 @@ export default Discourse.Route.extend({
);
if (parentCategorySlug) {
filter = `tags/c/${parentCategorySlug}/${categorySlug}/${tagId}/l/${topicFilter}`;
+ } else if (this.noSubcategories) {
+ filter = `tags/c/${categorySlug}/none/${tagId}/l/${topicFilter}`;
} else {
filter = `tags/c/${categorySlug}/${tagId}/l/${topicFilter}`;
}
@@ -161,7 +164,8 @@ export default Discourse.Route.extend({
category: this.category,
filterMode: this.filterMode,
navMode: this.navMode,
- tagNotification: this.tagNotification
+ tagNotification: this.tagNotification,
+ noSubcategories: this.noSubcategories
});
},
diff --git a/app/assets/javascripts/discourse/routes/topic-by-slug-or-id.js.es6 b/app/assets/javascripts/discourse/routes/topic-by-slug-or-id.js.es6
index dd5b8e444b..74556b57fc 100644
--- a/app/assets/javascripts/discourse/routes/topic-by-slug-or-id.js.es6
+++ b/app/assets/javascripts/discourse/routes/topic-by-slug-or-id.js.es6
@@ -1,7 +1,8 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { default as Topic, ID_CONSTRAINT } from "discourse/models/topic";
import DiscourseURL from "discourse/lib/url";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model(params) {
if (params.slugOrId.match(ID_CONSTRAINT)) {
return { url: `/t/topic/${params.slugOrId}` };
diff --git a/app/assets/javascripts/discourse/routes/topic-from-params.js.es6 b/app/assets/javascripts/discourse/routes/topic-from-params.js.es6
index c193cbe98c..08c4671236 100644
--- a/app/assets/javascripts/discourse/routes/topic-from-params.js.es6
+++ b/app/assets/javascripts/discourse/routes/topic-from-params.js.es6
@@ -1,8 +1,11 @@
+import { isEmpty } from "@ember/utils";
+import { scheduleOnce } from "@ember/runloop";
+import DiscourseRoute from "discourse/routes/discourse";
import DiscourseURL from "discourse/lib/url";
import Draft from "discourse/models/draft";
// This route is used for retrieving a topic based on params
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
// Avoid default model hook
model(params) {
return params;
@@ -56,7 +59,7 @@ export default Discourse.Route.extend({
topicController.subscribe();
// Highlight our post after the next render
- Ember.run.scheduleOnce("afterRender", () =>
+ scheduleOnce("afterRender", () =>
this.appEvents.trigger("post:highlight", closest)
);
@@ -66,7 +69,7 @@ export default Discourse.Route.extend({
}
DiscourseURL.jumpToPost(closest, opts);
- if (!Ember.isEmpty(topic.draft)) {
+ if (!isEmpty(topic.draft)) {
composerController.open({
draft: Draft.getLocal(topic.draft_key, topic.draft),
draftKey: topic.draft_key,
diff --git a/app/assets/javascripts/discourse/routes/topic.js.es6 b/app/assets/javascripts/discourse/routes/topic.js.es6
index 4782d2dab8..a6f3eba69a 100644
--- a/app/assets/javascripts/discourse/routes/topic.js.es6
+++ b/app/assets/javascripts/discourse/routes/topic.js.es6
@@ -1,3 +1,9 @@
+import { get } from "@ember/object";
+import { isEmpty } from "@ember/utils";
+import { cancel } from "@ember/runloop";
+import { scheduleOnce } from "@ember/runloop";
+import { later } from "@ember/runloop";
+import DiscourseRoute from "discourse/routes/discourse";
import DiscourseURL from "discourse/lib/url";
import { ID_CONSTRAINT } from "discourse/models/topic";
@@ -9,7 +15,7 @@ const SCROLL_DELAY = 500;
import showModal from "discourse/lib/show-modal";
-const TopicRoute = Discourse.Route.extend({
+const TopicRoute = DiscourseRoute.extend({
redirect() {
return this.redirectIfLoginRequired();
},
@@ -167,9 +173,9 @@ const TopicRoute = Discourse.Route.extend({
postUrl += "/" + currentPost;
}
- Ember.run.cancel(scheduledReplace);
+ cancel(scheduledReplace);
lastScrollPos = parseInt($(document).scrollTop(), 10);
- scheduledReplace = Ember.run.later(
+ scheduledReplace = later(
this,
"_replaceUnlessScrolling",
postUrl,
@@ -185,7 +191,7 @@ const TopicRoute = Discourse.Route.extend({
willTransition() {
this._super(...arguments);
- Ember.run.cancel(scheduledReplace);
+ cancel(scheduledReplace);
isTransitioning = true;
return true;
}
@@ -200,7 +206,7 @@ const TopicRoute = Discourse.Route.extend({
return;
}
lastScrollPos = currentPos;
- scheduledReplace = Ember.run.later(
+ scheduledReplace = later(
this,
"_replaceUnlessScrolling",
url,
@@ -210,13 +216,13 @@ const TopicRoute = Discourse.Route.extend({
setupParams(topic, params) {
const postStream = topic.get("postStream");
- postStream.set("summary", Ember.get(params, "filter") === "summary");
+ postStream.set("summary", get(params, "filter") === "summary");
- const usernames = Ember.get(params, "username_filters"),
+ const usernames = get(params, "username_filters"),
userFilters = postStream.get("userFilters");
userFilters.clear();
- if (!Ember.isEmpty(usernames) && usernames !== "undefined") {
+ if (!isEmpty(usernames) && usernames !== "undefined") {
userFilters.addObjects(usernames.split(","));
}
@@ -301,7 +307,7 @@ const TopicRoute = Discourse.Route.extend({
// We reset screen tracking every time a topic is entered
this.screenTrack.start(model.get("id"), controller);
- Ember.run.scheduleOnce("afterRender", () => {
+ scheduleOnce("afterRender", () => {
this.appEvents.trigger("header:update-topic", model);
});
}
diff --git a/app/assets/javascripts/discourse/routes/unknown.js.es6 b/app/assets/javascripts/discourse/routes/unknown.js.es6
index 4b2b993549..3df278df6f 100644
--- a/app/assets/javascripts/discourse/routes/unknown.js.es6
+++ b/app/assets/javascripts/discourse/routes/unknown.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
return ajax("/404-body", { dataType: "html" });
}
diff --git a/app/assets/javascripts/discourse/routes/user-activity-drafts.js.es6 b/app/assets/javascripts/discourse/routes/user-activity-drafts.js.es6
index 2ca94b05e5..392b9a6255 100644
--- a/app/assets/javascripts/discourse/routes/user-activity-drafts.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-activity-drafts.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
let userDraftsStream = this.modelFor("user").get("userDraftsStream");
return userDraftsStream.load(this.site).then(() => userDraftsStream);
diff --git a/app/assets/javascripts/discourse/routes/user-activity-stream.js.es6 b/app/assets/javascripts/discourse/routes/user-activity-stream.js.es6
index 8d9d1e8144..1aea1056cf 100644
--- a/app/assets/javascripts/discourse/routes/user-activity-stream.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-activity-stream.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import ViewingActionType from "discourse/mixins/viewing-action-type";
-export default Discourse.Route.extend(ViewingActionType, {
+export default DiscourseRoute.extend(ViewingActionType, {
queryParams: {
acting_username: { refreshModel: true }
},
diff --git a/app/assets/javascripts/discourse/routes/user-activity.js.es6 b/app/assets/javascripts/discourse/routes/user-activity.js.es6
index a827e3d998..f36beaf1d5 100644
--- a/app/assets/javascripts/discourse/routes/user-activity.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-activity.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
model() {
let user = this.modelFor("user");
if (user.get("profile_hidden")) {
diff --git a/app/assets/javascripts/discourse/routes/user-badges.js.es6 b/app/assets/javascripts/discourse/routes/user-badges.js.es6
index 0efe8069fc..ffe6008da9 100644
--- a/app/assets/javascripts/discourse/routes/user-badges.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-badges.js.es6
@@ -1,7 +1,8 @@
+import DiscourseRoute from "discourse/routes/discourse";
import ViewingActionType from "discourse/mixins/viewing-action-type";
import UserBadge from "discourse/models/user-badge";
-export default Discourse.Route.extend(ViewingActionType, {
+export default DiscourseRoute.extend(ViewingActionType, {
model() {
return UserBadge.findByUsername(
this.modelFor("user").get("username_lower"),
diff --git a/app/assets/javascripts/discourse/routes/user-index.js.es6 b/app/assets/javascripts/discourse/routes/user-index.js.es6
index eef87b16eb..ca51d8fce9 100644
--- a/app/assets/javascripts/discourse/routes/user-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
beforeModel() {
const { currentUser } = this;
const viewingMe =
diff --git a/app/assets/javascripts/discourse/routes/user-invited-index.js.es6 b/app/assets/javascripts/discourse/routes/user-invited-index.js.es6
index bf7a358215..721f4fb8b2 100644
--- a/app/assets/javascripts/discourse/routes/user-invited-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-invited-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
beforeModel: function() {
this.replaceWith("userInvited.show", "pending");
}
diff --git a/app/assets/javascripts/discourse/routes/user-invited-show.js.es6 b/app/assets/javascripts/discourse/routes/user-invited-show.js.es6
index 54f367b739..3cd83f79ce 100644
--- a/app/assets/javascripts/discourse/routes/user-invited-show.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-invited-show.js.es6
@@ -1,7 +1,8 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Invite from "discourse/models/invite";
import showModal from "discourse/lib/show-modal";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model(params) {
Invite.findInvitedCount(this.modelFor("user")).then(result =>
this.set("invitesCount", result)
diff --git a/app/assets/javascripts/discourse/routes/user-notifications-index.js.es6 b/app/assets/javascripts/discourse/routes/user-notifications-index.js.es6
index 1e998969a3..28f0041253 100644
--- a/app/assets/javascripts/discourse/routes/user-notifications-index.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-notifications-index.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
controllerName: "user-notifications",
renderTemplate() {
this.render("user/notifications-index");
diff --git a/app/assets/javascripts/discourse/routes/user-notifications.js.es6 b/app/assets/javascripts/discourse/routes/user-notifications.js.es6
index e4e65c7f9b..3feb837746 100644
--- a/app/assets/javascripts/discourse/routes/user-notifications.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-notifications.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import ViewingActionType from "discourse/mixins/viewing-action-type";
-export default Discourse.Route.extend(ViewingActionType, {
+export default DiscourseRoute.extend(ViewingActionType, {
renderTemplate() {
this.render("user/notifications");
},
diff --git a/app/assets/javascripts/discourse/routes/user-private-messages-group-archive.js.es6 b/app/assets/javascripts/discourse/routes/user-private-messages-group-archive.js.es6
index 0d37dac923..0aece428d2 100644
--- a/app/assets/javascripts/discourse/routes/user-private-messages-group-archive.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-private-messages-group-archive.js.es6
@@ -1,4 +1,5 @@
import createPMRoute from "discourse/routes/build-private-messages-route";
+import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
export default createPMRoute("groups", "private-messages-groups").extend({
groupName: null,
@@ -16,9 +17,11 @@ export default createPMRoute("groups", "private-messages-groups").extend({
model(params) {
const username = this.modelFor("user").get("username_lower");
- return this.store.findFiltered("topicList", {
- filter: `topics/private-messages-group/${username}/${params.name}/archive`
- });
+ const filter = `topics/private-messages-group/${username}/${params.name}/archive`;
+ const lastTopicList = findOrResetCachedTopicList(this.session, filter);
+ return lastTopicList
+ ? lastTopicList
+ : this.store.findFiltered("topicList", { filter });
},
afterModel(model) {
diff --git a/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6 b/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6
index cea1b022f4..971cb506cb 100644
--- a/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-private-messages-group.js.es6
@@ -1,4 +1,5 @@
import createPMRoute from "discourse/routes/build-private-messages-route";
+import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
export default createPMRoute("groups", "private-messages-groups").extend({
groupName: null,
@@ -11,9 +12,11 @@ export default createPMRoute("groups", "private-messages-groups").extend({
model(params) {
const username = this.modelFor("user").get("username_lower");
- return this.store.findFiltered("topicList", {
- filter: `topics/private-messages-group/${username}/${params.name}`
- });
+ const filter = `topics/private-messages-group/${username}/${params.name}`;
+ const lastTopicList = findOrResetCachedTopicList(this.session, filter);
+ return lastTopicList
+ ? lastTopicList
+ : this.store.findFiltered("topicList", { filter });
},
afterModel(model) {
diff --git a/app/assets/javascripts/discourse/routes/user-private-messages-tags.js.es6 b/app/assets/javascripts/discourse/routes/user-private-messages-tags.js.es6
index 7007920e38..cfe2d026bb 100644
--- a/app/assets/javascripts/discourse/routes/user-private-messages-tags.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-private-messages-tags.js.es6
@@ -1,12 +1,14 @@
+import EmberObject from "@ember/object";
+import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
model() {
const username = this.modelFor("user").get("username_lower");
return ajax(`/tags/personal_messages/${username}`)
.then(result => {
- return result.tags.map(tag => Ember.Object.create(tag));
+ return result.tags.map(tag => EmberObject.create(tag));
})
.catch(popupAjaxError);
},
diff --git a/app/assets/javascripts/discourse/routes/user-private-messages.js.es6 b/app/assets/javascripts/discourse/routes/user-private-messages.js.es6
index 2596727a6a..ef6854e056 100644
--- a/app/assets/javascripts/discourse/routes/user-private-messages.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-private-messages.js.es6
@@ -1,6 +1,8 @@
+import DiscourseRoute from "discourse/routes/discourse";
import Draft from "discourse/models/draft";
+import Composer from "discourse/models/composer";
-export default Discourse.Route.extend({
+export default DiscourseRoute.extend({
renderTemplate() {
this.render("user/messages");
},
@@ -17,7 +19,7 @@ export default Discourse.Route.extend({
if (data.draft) {
composerController.open({
draft: data.draft,
- draftKey: "new_private_message",
+ draftKey: Composer.NEW_PRIVATE_MESSAGE_KEY,
ignoreIfChanged: true,
draftSequence: data.draft_sequence
});
diff --git a/app/assets/javascripts/discourse/routes/user-summary.js.es6 b/app/assets/javascripts/discourse/routes/user-summary.js.es6
index 698d2f4edc..6827063517 100644
--- a/app/assets/javascripts/discourse/routes/user-summary.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-summary.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
showFooter: true,
model() {
diff --git a/app/assets/javascripts/discourse/routes/user-topic-list.js.es6 b/app/assets/javascripts/discourse/routes/user-topic-list.js.es6
index c82e0dceea..80f2c66734 100644
--- a/app/assets/javascripts/discourse/routes/user-topic-list.js.es6
+++ b/app/assets/javascripts/discourse/routes/user-topic-list.js.es6
@@ -1,6 +1,7 @@
+import DiscourseRoute from "discourse/routes/discourse";
import ViewingActionType from "discourse/mixins/viewing-action-type";
-export default Discourse.Route.extend(ViewingActionType, {
+export default DiscourseRoute.extend(ViewingActionType, {
renderTemplate() {
this.render("user-topics-list");
},
diff --git a/app/assets/javascripts/discourse/routes/user.js.es6 b/app/assets/javascripts/discourse/routes/user.js.es6
index 4eaaa4c910..af8d85ccf0 100644
--- a/app/assets/javascripts/discourse/routes/user.js.es6
+++ b/app/assets/javascripts/discourse/routes/user.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
titleToken() {
const username = this.modelFor("user").username;
if (username) {
diff --git a/app/assets/javascripts/discourse/routes/users.js.es6 b/app/assets/javascripts/discourse/routes/users.js.es6
index 009ee9e88d..b500a985b5 100644
--- a/app/assets/javascripts/discourse/routes/users.js.es6
+++ b/app/assets/javascripts/discourse/routes/users.js.es6
@@ -1,4 +1,6 @@
-export default Discourse.Route.extend({
+import DiscourseRoute from "discourse/routes/discourse";
+
+export default DiscourseRoute.extend({
queryParams: {
period: { refreshModel: true },
order: { refreshModel: true },
diff --git a/app/assets/javascripts/discourse/services/app-events.js.es6 b/app/assets/javascripts/discourse/services/app-events.js.es6
index 5967568ef3..fa73e9d463 100644
--- a/app/assets/javascripts/discourse/services/app-events.js.es6
+++ b/app/assets/javascripts/discourse/services/app-events.js.es6
@@ -1,6 +1,7 @@
import deprecated from "discourse-common/lib/deprecated";
+import Service from "@ember/service";
-export default Ember.Service.extend(Ember.Evented, {
+export default Service.extend(Ember.Evented, {
_events: {},
on() {
diff --git a/app/assets/javascripts/discourse/services/emoji-store.js.es6 b/app/assets/javascripts/discourse/services/emoji-store.js.es6
index 7c7a5d082a..19fbd662fc 100644
--- a/app/assets/javascripts/discourse/services/emoji-store.js.es6
+++ b/app/assets/javascripts/discourse/services/emoji-store.js.es6
@@ -1,11 +1,12 @@
import KeyValueStore from "discourse/lib/key-value-store";
+import Service from "@ember/service";
const EMOJI_USAGE = "emojiUsage";
const EMOJI_SELECTED_DIVERSITY = "emojiSelectedDiversity";
const TRACKED_EMOJIS = 15;
const STORE_NAMESPACE = "discourse_emojis_";
-export default Ember.Service.extend({
+export default Service.extend({
init() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/services/logs-notice.js.es6 b/app/assets/javascripts/discourse/services/logs-notice.js.es6
index f70e021992..73961054a1 100644
--- a/app/assets/javascripts/discourse/services/logs-notice.js.es6
+++ b/app/assets/javascripts/discourse/services/logs-notice.js.es6
@@ -1,3 +1,5 @@
+import { isEmpty } from "@ember/utils";
+import EmberObject from "@ember/object";
import {
default as computed,
on,
@@ -7,7 +9,7 @@ import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
const LOGS_NOTICE_KEY = "logs-notice-text";
-const LogsNotice = Ember.Object.extend({
+const LogsNotice = EmberObject.extend({
text: "",
@on("init")
@@ -47,7 +49,7 @@ const LogsNotice = Ember.Object.extend({
@computed("text")
isEmpty(text) {
- return Ember.isEmpty(text);
+ return isEmpty(text);
},
@computed("text")
@@ -61,8 +63,8 @@ const LogsNotice = Ember.Object.extend({
},
@computed("isEmpty", "isAdmin")
- hidden(isEmpty, isAdmin) {
- return !isAdmin || isEmpty;
+ hidden(thisIsEmpty, isAdmin) {
+ return !isAdmin || thisIsEmpty;
},
@observes("text")
diff --git a/app/assets/javascripts/discourse/services/search.js.es6 b/app/assets/javascripts/discourse/services/search.js.es6
index 2a47789da4..641e35e482 100644
--- a/app/assets/javascripts/discourse/services/search.js.es6
+++ b/app/assets/javascripts/discourse/services/search.js.es6
@@ -1,9 +1,11 @@
+import { get } from "@ember/object";
+import EmberObject from "@ember/object";
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
-export default Ember.Object.extend({
+export default EmberObject.extend({
searchContextEnabled: false, // checkbox to scope search
searchContext: null,
term: null,
@@ -18,7 +20,7 @@ export default Ember.Object.extend({
contextType: {
get(searchContext) {
if (searchContext) {
- return Ember.get(searchContext, "type");
+ return get(searchContext, "type");
}
},
set(value, searchContext) {
diff --git a/app/assets/javascripts/discourse/services/theme-settings.js.es6 b/app/assets/javascripts/discourse/services/theme-settings.js.es6
index 1ff2300f7f..032024b56b 100644
--- a/app/assets/javascripts/discourse/services/theme-settings.js.es6
+++ b/app/assets/javascripts/discourse/services/theme-settings.js.es6
@@ -1,4 +1,7 @@
-export default Ember.Service.extend({
+import { get } from "@ember/object";
+import Service from "@ember/service";
+
+export default Service.extend({
settings: null,
init() {
@@ -12,7 +15,7 @@ export default Ember.Service.extend({
getSetting(themeId, settingsKey) {
if (this._settings[themeId]) {
- return Ember.get(this._settings[themeId], settingsKey);
+ return get(this._settings[themeId], settingsKey);
}
return null;
},
diff --git a/app/assets/javascripts/discourse/templates/badges/show.hbs b/app/assets/javascripts/discourse/templates/badges/show.hbs
index 933bc48de8..9eeb3d7fa2 100644
--- a/app/assets/javascripts/discourse/templates/badges/show.hbs
+++ b/app/assets/javascripts/discourse/templates/badges/show.hbs
@@ -13,7 +13,7 @@
{{i18n 'badges.allow_title'}}
{{d-button
- class="btn btn-default pad-left no-text"
+ class="btn-default pad-left"
action=(action "toggleSetUserTitle")
icon="pencil-alt"}}
diff --git a/app/assets/javascripts/discourse/templates/components/badge-title.hbs b/app/assets/javascripts/discourse/templates/components/badge-title.hbs
index 23b1f4e22d..5361595199 100644
--- a/app/assets/javascripts/discourse/templates/components/badge-title.hbs
+++ b/app/assets/javascripts/discourse/templates/components/badge-title.hbs
@@ -18,7 +18,11 @@
- {{savingStatus}}
+ {{d-button
+ class="btn-primary"
+ action=(action "save")
+ disabled=saving
+ label=(if saving "saving" "save")}}
{{#if saved}}{{i18n 'saved'}}{{/if}}
diff --git a/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs b/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs
index d1d105121e..44d9dc579d 100644
--- a/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs
+++ b/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs
@@ -18,7 +18,10 @@
canBulkSelect=canBulkSelect
selected=selected
skipHeader=skipHeader
- tagsForUser=tagsForUser}}
+ tagsForUser=tagsForUser
+ onScroll=onScroll
+ scrollOnLoad=scrollOnLoad}}
+
{{else}}
{{#unless loadingMore}}
diff --git a/app/assets/javascripts/discourse/templates/components/categories-only.hbs b/app/assets/javascripts/discourse/templates/components/categories-only.hbs
index 4f93c8a316..762752097b 100644
--- a/app/assets/javascripts/discourse/templates/components/categories-only.hbs
+++ b/app/assets/javascripts/discourse/templates/components/categories-only.hbs
@@ -20,12 +20,14 @@
{{#if c.subcategories}}
- {{#each c.subcategories as |s|}}
-
- {{category-title-before category=s}}
- {{category-link s hideParent="true"}}
- {{category-unread category=s}}
-
+ {{#each c.subcategories as |subcategory|}}
+ {{#unless subcategory.isMuted}}
+
+ {{category-title-before category=subcategory}}
+ {{category-link subcategory hideParent="true"}}
+ {{category-unread category=subcategory}}
+
+ {{/unless}}
{{/each}}
{{/if}}
diff --git a/app/assets/javascripts/discourse/templates/components/composer-title.hbs b/app/assets/javascripts/discourse/templates/components/composer-title.hbs
index 76f63dac1f..a8483595de 100644
--- a/app/assets/javascripts/discourse/templates/components/composer-title.hbs
+++ b/app/assets/javascripts/discourse/templates/components/composer-title.hbs
@@ -3,7 +3,7 @@
id="reply-title"
maxLength=titleMaxLength
placeholderKey=composer.titlePlaceholder
- disabled=composer.loading
+ disabled=disabled
autocomplete="discourse"}}
{{popup-input-tip validation=validation}}
diff --git a/app/assets/javascripts/discourse/templates/components/create-topic-button.hbs b/app/assets/javascripts/discourse/templates/components/create-topic-button.hbs
index e99673f9cb..3a0e3ebfa9 100644
--- a/app/assets/javascripts/discourse/templates/components/create-topic-button.hbs
+++ b/app/assets/javascripts/discourse/templates/components/create-topic-button.hbs
@@ -1,7 +1,7 @@
{{#if canCreateTopic}}
{{d-button
+ class="btn-default"
id="create-topic"
- class="btn btn-default"
action=action
icon="plus"
disabled=disabled
diff --git a/app/assets/javascripts/discourse/templates/components/d-modal.hbs b/app/assets/javascripts/discourse/templates/components/d-modal.hbs
index 4e7cd0dca2..6c6106bbad 100644
--- a/app/assets/javascripts/discourse/templates/components/d-modal.hbs
+++ b/app/assets/javascripts/discourse/templates/components/d-modal.hbs
@@ -3,11 +3,7 @@