diff --git a/app/assets/javascripts/admin/addon/models/admin-dashboard.js b/app/assets/javascripts/admin/addon/models/admin-dashboard.js
index c0c9f86702c..c261a424411 100644
--- a/app/assets/javascripts/admin/addon/models/admin-dashboard.js
+++ b/app/assets/javascripts/admin/addon/models/admin-dashboard.js
@@ -7,19 +7,17 @@ const GENERAL_ATTRIBUTES = [
"release_notes_link",
];
-const AdminDashboard = EmberObject.extend({});
-
-AdminDashboard.reopenClass({
- fetch() {
+export default class AdminDashboard extends EmberObject {
+ static fetch() {
return ajax("/admin/dashboard.json").then((json) => {
const model = AdminDashboard.create();
model.set("version_check", json.version_check);
return model;
});
- },
+ }
- fetchGeneral() {
+ static fetchGeneral() {
return ajax("/admin/dashboard/general.json").then((json) => {
const model = AdminDashboard.create();
@@ -34,15 +32,13 @@ AdminDashboard.reopenClass({
return model;
});
- },
+ }
- fetchProblems() {
+ static fetchProblems() {
return ajax("/admin/dashboard/problems.json").then((json) => {
const model = AdminDashboard.create(json);
model.set("loaded", true);
return model;
});
- },
-});
-
-export default AdminDashboard;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/admin-user.js b/app/assets/javascripts/admin/addon/models/admin-user.js
index a61980bc61a..8621fbfd494 100644
--- a/app/assets/javascripts/admin/addon/models/admin-user.js
+++ b/app/assets/javascripts/admin/addon/models/admin-user.js
@@ -10,14 +10,30 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import { propertyNotEqual } from "discourse/lib/computed";
import { userPath } from "discourse/lib/url";
-const wrapAdmin = (user) => (user ? AdminUser.create(user) : null);
+export default class AdminUser extends User {
+ static find(user_id) {
+ return ajax(`/admin/users/${user_id}.json`).then((result) => {
+ result.loadedDetails = true;
+ return AdminUser.create(result);
+ });
+ }
-const AdminUser = User.extend({
- adminUserView: true,
- customGroups: filter("groups", (g) => !g.automatic && Group.create(g)),
- automaticGroups: filter("groups", (g) => g.automatic && Group.create(g)),
+ static findAll(query, userFilter) {
+ return ajax(`/admin/users/list/${query}.json`, {
+ data: userFilter,
+ }).then((users) => users.map((u) => AdminUser.create(u)));
+ }
- canViewProfile: or("active", "staged"),
+ adminUserView = true;
+
+ @filter("groups", (g) => !g.automatic && Group.create(g)) customGroups;
+ @filter("groups", (g) => g.automatic && Group.create(g)) automaticGroups;
+ @or("active", "staged") canViewProfile;
+ @gt("bounce_score", 0) canResetBounceScore;
+ @propertyNotEqual("originalTrustLevel", "trust_level") dirty;
+ @lt("trust_level", 4) canLockTrustLevel;
+ @not("staff") canSuspend;
+ @not("staff") canSilence;
@discourseComputed("bounce_score", "reset_bounce_score_after")
bounceScore(bounce_score, reset_bounce_score_after) {
@@ -28,7 +44,7 @@ const AdminUser = User.extend({
} else {
return bounce_score;
}
- },
+ }
@discourseComputed("bounce_score")
bounceScoreExplanation(bounce_score) {
@@ -39,14 +55,12 @@ const AdminUser = User.extend({
} else {
return I18n.t("admin.user.bounce_score_explanation.threshold_reached");
}
- },
+ }
@discourseComputed
bounceLink() {
return getURL("/admin/email/bounced");
- },
-
- canResetBounceScore: gt("bounce_score", 0),
+ }
resetBounceScore() {
return ajax(`/admin/users/${this.id}/reset_bounce_score`, {
@@ -57,14 +71,14 @@ const AdminUser = User.extend({
reset_bounce_score_after: null,
})
);
- },
+ }
groupAdded(added) {
return ajax(`/admin/users/${this.id}/groups`, {
type: "POST",
data: { group_id: added.id },
}).then(() => this.groups.pushObject(added));
- },
+ }
groupRemoved(groupId) {
return ajax(`/admin/users/${this.id}/groups/${groupId}`, {
@@ -75,13 +89,13 @@ const AdminUser = User.extend({
this.set("primary_group_id", null);
}
});
- },
+ }
deleteAllPosts() {
return ajax(`/admin/users/${this.get("id")}/delete_posts_batch`, {
type: "PUT",
});
- },
+ }
revokeAdmin() {
return ajax(`/admin/users/${this.id}/revoke_admin`, {
@@ -97,7 +111,7 @@ const AdminUser = User.extend({
can_delete_all_posts: resp.can_delete_all_posts,
});
});
- },
+ }
grantAdmin(data) {
return ajax(`/admin/users/${this.id}/grant_admin`, {
@@ -114,7 +128,7 @@ const AdminUser = User.extend({
return resp;
});
- },
+ }
revokeModeration() {
return ajax(`/admin/users/${this.id}/revoke_moderation`, {
@@ -130,7 +144,7 @@ const AdminUser = User.extend({
});
})
.catch(popupAjaxError);
- },
+ }
grantModeration() {
return ajax(`/admin/users/${this.id}/grant_moderation`, {
@@ -146,7 +160,7 @@ const AdminUser = User.extend({
});
})
.catch(popupAjaxError);
- },
+ }
disableSecondFactor() {
return ajax(`/admin/users/${this.id}/disable_second_factor`, {
@@ -156,7 +170,7 @@ const AdminUser = User.extend({
this.set("second_factor_enabled", false);
})
.catch(popupAjaxError);
- },
+ }
approve(approvedBy) {
return ajax(`/admin/users/${this.id}/approve`, {
@@ -168,83 +182,76 @@ const AdminUser = User.extend({
approved_by: approvedBy,
});
});
- },
+ }
setOriginalTrustLevel() {
this.set("originalTrustLevel", this.trust_level);
- },
-
- dirty: propertyNotEqual("originalTrustLevel", "trust_level"),
+ }
saveTrustLevel() {
return ajax(`/admin/users/${this.id}/trust_level`, {
type: "PUT",
data: { level: this.trust_level },
});
- },
+ }
restoreTrustLevel() {
this.set("trust_level", this.originalTrustLevel);
- },
+ }
lockTrustLevel(locked) {
return ajax(`/admin/users/${this.id}/trust_level_lock`, {
type: "PUT",
data: { locked: !!locked },
});
- },
-
- canLockTrustLevel: lt("trust_level", 4),
-
- canSuspend: not("staff"),
- canSilence: not("staff"),
+ }
@discourseComputed("suspended_till", "suspended_at")
suspendDuration(suspendedTill, suspendedAt) {
suspendedAt = moment(suspendedAt);
suspendedTill = moment(suspendedTill);
return suspendedAt.format("L") + " - " + suspendedTill.format("L");
- },
+ }
suspend(data) {
return ajax(`/admin/users/${this.id}/suspend`, {
type: "PUT",
data,
}).then((result) => this.setProperties(result.suspension));
- },
+ }
unsuspend() {
return ajax(`/admin/users/${this.id}/unsuspend`, {
type: "PUT",
}).then((result) => this.setProperties(result.suspension));
- },
+ }
logOut() {
return ajax("/admin/users/" + this.id + "/log_out", {
type: "POST",
data: { username_or_email: this.username },
});
- },
+ }
impersonate() {
return ajax("/admin/impersonate", {
type: "POST",
data: { username_or_email: this.username },
});
- },
+ }
activate() {
return ajax(`/admin/users/${this.id}/activate`, {
type: "PUT",
});
- },
+ }
deactivate() {
return ajax(`/admin/users/${this.id}/deactivate`, {
type: "PUT",
data: { context: document.location.pathname },
});
- },
+ }
unsilence() {
this.set("silencingUser", true);
@@ -254,7 +261,7 @@ const AdminUser = User.extend({
})
.then((result) => this.setProperties(result.unsilence))
.finally(() => this.set("silencingUser", false));
- },
+ }
silence(data) {
this.set("silencingUser", true);
@@ -265,20 +272,20 @@ const AdminUser = User.extend({
})
.then((result) => this.setProperties(result.silence))
.finally(() => this.set("silencingUser", false));
- },
+ }
sendActivationEmail() {
return ajax(userPath("action/send_activation_email"), {
type: "POST",
data: { username: this.username },
});
- },
+ }
anonymize() {
return ajax(`/admin/users/${this.id}/anonymize.json`, {
type: "PUT",
});
- },
+ }
destroy(formData) {
return ajax(`/admin/users/${this.id}.json`, {
@@ -295,14 +302,14 @@ const AdminUser = User.extend({
.catch(() => {
this.find(this.id).then((u) => this.setProperties(u));
});
- },
+ }
merge(formData) {
return ajax(`/admin/users/${this.id}/merge.json`, {
type: "POST",
data: formData,
});
- },
+ }
loadDetails() {
if (this.loadedDetails) {
@@ -313,23 +320,29 @@ const AdminUser = User.extend({
const userProperties = Object.assign(result, { loadedDetails: true });
this.setProperties(userProperties);
});
- },
+ }
@discourseComputed("tl3_requirements")
tl3Requirements(requirements) {
if (requirements) {
return this.store.createRecord("tl3Requirements", requirements);
}
- },
+ }
@discourseComputed("suspended_by")
- suspendedBy: wrapAdmin,
+ suspendedBy(user) {
+ return user ? AdminUser.create(user) : null;
+ }
@discourseComputed("silenced_by")
- silencedBy: wrapAdmin,
+ silencedBy(user) {
+ return user ? AdminUser.create(user) : null;
+ }
@discourseComputed("approved_by")
- approvedBy: wrapAdmin,
+ approvedBy(user) {
+ return user ? AdminUser.create(user) : null;
+ }
deleteSSORecord() {
return ajax(`/admin/users/${this.id}/sso_record.json`, {
@@ -339,22 +352,5 @@ const AdminUser = User.extend({
this.set("single_sign_on_record", null);
})
.catch(popupAjaxError);
- },
-});
-
-AdminUser.reopenClass({
- find(user_id) {
- return ajax(`/admin/users/${user_id}.json`).then((result) => {
- result.loadedDetails = true;
- return AdminUser.create(result);
- });
- },
-
- findAll(query, userFilter) {
- return ajax(`/admin/users/list/${query}.json`, {
- data: userFilter,
- }).then((users) => users.map((u) => AdminUser.create(u)));
- },
-});
-
-export default AdminUser;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/api-key.js b/app/assets/javascripts/admin/addon/models/api-key.js
index be5475a4abc..f40d643270b 100644
--- a/app/assets/javascripts/admin/addon/models/api-key.js
+++ b/app/assets/javascripts/admin/addon/models/api-key.js
@@ -1,24 +1,26 @@
+import { computed } from "@ember/object";
import AdminUser from "admin/models/admin-user";
import RestModel from "discourse/models/rest";
import { ajax } from "discourse/lib/ajax";
-import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import { fmt } from "discourse/lib/computed";
-const ApiKey = RestModel.extend({
- user: 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;
- },
- }),
+export default class ApiKey extends RestModel {
+ @fmt("truncated_key", "%@...") truncatedKey;
+
+ @computed("_user")
+ get user() {
+ return this._user;
+ }
+
+ set user(value) {
+ if (value && !(value instanceof AdminUser)) {
+ this.set("_user", AdminUser.create(value));
+ } else {
+ this.set("_user", value);
+ }
+ return this._user;
+ }
@discourseComputed("description")
shortDescription(description) {
@@ -26,32 +28,28 @@ const ApiKey = RestModel.extend({
return description;
}
return `${description.substring(0, 40)}...`;
- },
-
- truncatedKey: fmt("truncated_key", "%@..."),
+ }
revoke() {
return ajax(`${this.basePath}/revoke`, {
type: "POST",
}).then((result) => this.setProperties(result.api_key));
- },
+ }
undoRevoke() {
return ajax(`${this.basePath}/undo-revoke`, {
type: "POST",
}).then((result) => this.setProperties(result.api_key));
- },
+ }
createProperties() {
return this.getProperties("description", "username", "scopes");
- },
+ }
@discourseComputed()
basePath() {
return this.store
.adapterFor("api-key")
.pathFor(this.store, "api-key", this.id);
- },
-});
-
-export default ApiKey;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/backup-status.js b/app/assets/javascripts/admin/addon/models/backup-status.js
index dffad0d0609..e9ee065f3e2 100644
--- a/app/assets/javascripts/admin/addon/models/backup-status.js
+++ b/app/assets/javascripts/admin/addon/models/backup-status.js
@@ -1,12 +1,12 @@
+import { not } from "@ember/object/computed";
import EmberObject from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
-import { not } from "@ember/object/computed";
-export default EmberObject.extend({
- restoreDisabled: not("restoreEnabled"),
+export default class BackupStatus extends EmberObject {
+ @not("restoreEnabled") restoreDisabled;
@discourseComputed("allowRestore", "isOperationRunning")
restoreEnabled(allowRestore, isOperationRunning) {
return allowRestore && !isOperationRunning;
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/backup.js b/app/assets/javascripts/admin/addon/models/backup.js
index 717192e8ac3..9708f9589bc 100644
--- a/app/assets/javascripts/admin/addon/models/backup.js
+++ b/app/assets/javascripts/admin/addon/models/backup.js
@@ -2,25 +2,12 @@ import EmberObject from "@ember/object";
import MessageBus from "message-bus-client";
import { ajax } from "discourse/lib/ajax";
-const Backup = EmberObject.extend({
- destroy() {
- return ajax("/admin/backups/" + this.filename, { type: "DELETE" });
- },
-
- restore() {
- return ajax("/admin/backups/" + this.filename + "/restore", {
- type: "POST",
- data: { client_id: MessageBus.clientId },
- });
- },
-});
-
-Backup.reopenClass({
- find() {
+export default class Backup extends EmberObject {
+ static find() {
return ajax("/admin/backups.json");
- },
+ }
- start(withUploads) {
+ static start(withUploads) {
if (withUploads === undefined) {
withUploads = true;
}
@@ -31,19 +18,28 @@ Backup.reopenClass({
client_id: MessageBus.clientId,
},
});
- },
+ }
- cancel() {
+ static cancel() {
return ajax("/admin/backups/cancel.json", {
type: "DELETE",
});
- },
+ }
- rollback() {
+ static rollback() {
return ajax("/admin/backups/rollback.json", {
type: "POST",
});
- },
-});
+ }
-export default Backup;
+ destroy() {
+ return ajax("/admin/backups/" + this.filename, { type: "DELETE" });
+ }
+
+ restore() {
+ return ajax("/admin/backups/" + this.filename + "/restore", {
+ type: "POST",
+ data: { client_id: MessageBus.clientId },
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/color-scheme-color.js b/app/assets/javascripts/admin/addon/models/color-scheme-color.js
index 24beb9130ca..72efcb32c13 100644
--- a/app/assets/javascripts/admin/addon/models/color-scheme-color.js
+++ b/app/assets/javascripts/admin/addon/models/color-scheme-color.js
@@ -1,19 +1,19 @@
-import discourseComputed, {
- observes,
- on,
-} from "discourse-common/utils/decorators";
+import discourseComputed from "discourse-common/utils/decorators";
+import { observes, on } from "@ember-decorators/object";
import EmberObject from "@ember/object";
import I18n from "I18n";
import { propertyNotEqual } from "discourse/lib/computed";
-const ColorSchemeColor = EmberObject.extend({
+export default class ColorSchemeColor extends EmberObject {
+ // Whether the current value is different than Discourse's default color scheme.
+ @propertyNotEqual("hex", "default_hex") overridden;
@on("init")
startTrackingChanges() {
this.set("originals", { hex: this.hex || "FFFFFF" });
// force changed property to be recalculated
this.notifyPropertyChange("hex");
- },
+ }
// Whether value has changed since it was last saved.
@discourseComputed("hex")
@@ -26,26 +26,23 @@ const ColorSchemeColor = EmberObject.extend({
}
return false;
- },
-
- // Whether the current value is different than Discourse's default color scheme.
- overridden: propertyNotEqual("hex", "default_hex"),
+ }
// Whether the saved value is different than Discourse's default color scheme.
@discourseComputed("default_hex", "hex")
savedIsOverriden(defaultHex) {
return this.originals.hex !== defaultHex;
- },
+ }
revert() {
this.set("hex", this.default_hex);
- },
+ }
undo() {
if (this.originals) {
this.set("hex", this.originals.hex);
}
- },
+ }
@discourseComputed("name")
translatedName(name) {
@@ -54,7 +51,7 @@ const ColorSchemeColor = EmberObject.extend({
} else {
return name;
}
- },
+ }
@discourseComputed("name")
description(name) {
@@ -63,7 +60,7 @@ const ColorSchemeColor = EmberObject.extend({
} else {
return "";
}
- },
+ }
/**
brightness returns a number between 0 (darkest) to 255 (brightest).
@@ -90,19 +87,17 @@ const ColorSchemeColor = EmberObject.extend({
1000
);
}
- },
+ }
@observes("hex")
hexValueChanged() {
if (this.hex) {
this.set("hex", this.hex.toString().replace(/[^0-9a-fA-F]/g, ""));
}
- },
+ }
@discourseComputed("hex")
valid(hex) {
return hex.match(/^([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/) !== null;
- },
-});
-
-export default ColorSchemeColor;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/color-scheme.js b/app/assets/javascripts/admin/addon/models/color-scheme.js
index e1b73ad14e8..53f8ea7eeda 100644
--- a/app/assets/javascripts/admin/addon/models/color-scheme.js
+++ b/app/assets/javascripts/admin/addon/models/color-scheme.js
@@ -1,3 +1,4 @@
+import { not } from "@ember/object/computed";
import { A } from "@ember/array";
import ArrayProxy from "@ember/array/proxy";
import ColorSchemeColor from "admin/models/color-scheme-color";
@@ -5,26 +6,56 @@ import EmberObject from "@ember/object";
import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-import { not } from "@ember/object/computed";
-const ColorScheme = EmberObject.extend({
+class ColorSchemes extends ArrayProxy {}
+
+export default class ColorScheme extends EmberObject {
+ static findAll() {
+ const colorSchemes = ColorSchemes.create({ content: [], loading: true });
+ return ajax("/admin/color_schemes").then((all) => {
+ all.forEach((colorScheme) => {
+ colorSchemes.pushObject(
+ ColorScheme.create({
+ id: colorScheme.id,
+ name: colorScheme.name,
+ is_base: colorScheme.is_base,
+ theme_id: colorScheme.theme_id,
+ theme_name: colorScheme.theme_name,
+ base_scheme_id: colorScheme.base_scheme_id,
+ user_selectable: colorScheme.user_selectable,
+ colors: colorScheme.colors.map((c) => {
+ return ColorSchemeColor.create({
+ name: c.name,
+ hex: c.hex,
+ default_hex: c.default_hex,
+ is_advanced: c.is_advanced,
+ });
+ }),
+ })
+ );
+ });
+ return colorSchemes;
+ });
+ }
+
+ @not("id") newRecord;
init() {
- this._super(...arguments);
+ super.init(...arguments);
this.startTrackingChanges();
- },
+ }
@discourseComputed
description() {
return "" + this.name;
- },
+ }
startTrackingChanges() {
this.set("originals", {
name: this.name,
user_selectable: this.user_selectable,
});
- },
+ }
schemeJson() {
const buffer = [];
@@ -33,7 +64,7 @@ const ColorScheme = EmberObject.extend({
});
return [`"${this.name}": {`, buffer.join(",\n"), "}"].join("\n");
- },
+ }
copy() {
const newScheme = ColorScheme.create({
@@ -47,7 +78,7 @@ const ColorScheme = EmberObject.extend({
);
});
return newScheme;
- },
+ }
@discourseComputed(
"name",
@@ -70,7 +101,7 @@ const ColorScheme = EmberObject.extend({
}
return false;
- },
+ }
@discourseComputed("changed")
disableSave(changed) {
@@ -79,9 +110,7 @@ const ColorScheme = EmberObject.extend({
}
return !changed || this.saving || this.colors.any((c) => !c.get("valid"));
- },
-
- newRecord: not("id"),
+ }
save(opts) {
if (this.is_base || this.disableSave) {
@@ -124,7 +153,7 @@ const ColorScheme = EmberObject.extend({
this.setProperties({ savingStatus: I18n.t("saved"), saving: false });
this.notifyPropertyChange("description");
});
- },
+ }
updateUserSelectable(value) {
if (!this.id) {
@@ -137,45 +166,11 @@ const ColorScheme = EmberObject.extend({
dataType: "json",
contentType: "application/json",
});
- },
+ }
destroy() {
if (this.id) {
return ajax(`/admin/color_schemes/${this.id}`, { type: "DELETE" });
}
- },
-});
-
-const ColorSchemes = ArrayProxy.extend({});
-
-ColorScheme.reopenClass({
- findAll() {
- const colorSchemes = ColorSchemes.create({ content: [], loading: true });
- return ajax("/admin/color_schemes").then((all) => {
- all.forEach((colorScheme) => {
- colorSchemes.pushObject(
- ColorScheme.create({
- id: colorScheme.id,
- name: colorScheme.name,
- is_base: colorScheme.is_base,
- theme_id: colorScheme.theme_id,
- theme_name: colorScheme.theme_name,
- base_scheme_id: colorScheme.base_scheme_id,
- user_selectable: colorScheme.user_selectable,
- colors: colorScheme.colors.map((c) => {
- return ColorSchemeColor.create({
- name: c.name,
- hex: c.hex,
- default_hex: c.default_hex,
- is_advanced: c.is_advanced,
- });
- }),
- })
- );
- });
- return colorSchemes;
- });
- },
-});
-
-export default ColorScheme;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/email-log.js b/app/assets/javascripts/admin/addon/models/email-log.js
index 6565611974a..18034d9f949 100644
--- a/app/assets/javascripts/admin/addon/models/email-log.js
+++ b/app/assets/javascripts/admin/addon/models/email-log.js
@@ -3,10 +3,8 @@ import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import getURL from "discourse-common/lib/get-url";
-const EmailLog = EmberObject.extend({});
-
-EmailLog.reopenClass({
- create(attrs) {
+export default class EmailLog extends EmberObject {
+ static create(attrs) {
attrs = attrs || {};
if (attrs.user) {
@@ -17,10 +15,10 @@ EmailLog.reopenClass({
attrs.post_url = getURL(attrs.post_url);
}
- return this._super(attrs);
- },
+ return super.create(attrs);
+ }
- findAll(filter, offset) {
+ static findAll(filter, offset) {
filter = filter || {};
offset = offset || 0;
@@ -30,7 +28,5 @@ EmailLog.reopenClass({
return ajax(`/admin/email/${status}.json?offset=${offset}`, {
data: filter,
}).then((logs) => logs.map((log) => EmailLog.create(log)));
- },
-});
-
-export default EmailLog;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/email-preview.js b/app/assets/javascripts/admin/addon/models/email-preview.js
index 1a709db82bb..3de69dcb077 100644
--- a/app/assets/javascripts/admin/addon/models/email-preview.js
+++ b/app/assets/javascripts/admin/addon/models/email-preview.js
@@ -1,25 +1,21 @@
import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
-const EmailPreview = EmberObject.extend({});
-
-export function oneWeekAgo() {
- return moment().locale("en").subtract(7, "days").format("YYYY-MM-DD");
-}
-
-EmailPreview.reopenClass({
- findDigest(username, lastSeenAt) {
+export default class EmailPreview extends EmberObject {
+ static findDigest(username, lastSeenAt) {
return ajax("/admin/email/preview-digest.json", {
data: { last_seen_at: lastSeenAt || oneWeekAgo(), username },
}).then((result) => EmailPreview.create(result));
- },
+ }
- sendDigest(username, lastSeenAt, email) {
+ static sendDigest(username, lastSeenAt, email) {
return ajax("/admin/email/send-digest.json", {
type: "POST",
data: { last_seen_at: lastSeenAt || oneWeekAgo(), username, email },
});
- },
-});
+ }
+}
-export default EmailPreview;
+export function oneWeekAgo() {
+ return moment().locale("en").subtract(7, "days").format("YYYY-MM-DD");
+}
diff --git a/app/assets/javascripts/admin/addon/models/email-settings.js b/app/assets/javascripts/admin/addon/models/email-settings.js
index aa4a245f009..cfddf2f6a9a 100644
--- a/app/assets/javascripts/admin/addon/models/email-settings.js
+++ b/app/assets/javascripts/admin/addon/models/email-settings.js
@@ -1,14 +1,10 @@
import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
-const EmailSettings = EmberObject.extend({});
-
-EmailSettings.reopenClass({
- find() {
+export default class EmailSettings extends EmberObject {
+ static find() {
return ajax("/admin/email.json").then(function (settings) {
return EmailSettings.create(settings);
});
- },
-});
-
-export default EmailSettings;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/email-style.js b/app/assets/javascripts/admin/addon/models/email-style.js
index 3dd991d70ac..2824539a7a6 100644
--- a/app/assets/javascripts/admin/addon/models/email-style.js
+++ b/app/assets/javascripts/admin/addon/models/email-style.js
@@ -1,10 +1,10 @@
import RestModel from "discourse/models/rest";
-export default RestModel.extend({
- changed: false,
+export default class EmailStyle extends RestModel {
+ changed = false;
setField(fieldName, value) {
this.set(`${fieldName}`, value);
this.set("changed", true);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/email-template.js b/app/assets/javascripts/admin/addon/models/email-template.js
index 19936a6a976..f3d8c514cbd 100644
--- a/app/assets/javascripts/admin/addon/models/email-template.js
+++ b/app/assets/javascripts/admin/addon/models/email-template.js
@@ -2,12 +2,12 @@ import RestModel from "discourse/models/rest";
import { ajax } from "discourse/lib/ajax";
import { getProperties } from "@ember/object";
-export default RestModel.extend({
+export default class EmailTemplate extends RestModel {
revert() {
return ajax(`/admin/customize/email_templates/${this.id}`, {
type: "DELETE",
}).then((result) =>
getProperties(result.email_template, "subject", "body", "can_revert")
);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/flag-type.js b/app/assets/javascripts/admin/addon/models/flag-type.js
index 5859584ce7f..3bb399fc2e5 100644
--- a/app/assets/javascripts/admin/addon/models/flag-type.js
+++ b/app/assets/javascripts/admin/addon/models/flag-type.js
@@ -2,9 +2,9 @@ import I18n from "I18n";
import RestModel from "discourse/models/rest";
import discourseComputed from "discourse-common/utils/decorators";
-export default RestModel.extend({
+export default class FlagType extends RestModel {
@discourseComputed("id")
name(id) {
return I18n.t(`admin.flags.summary.action_type_${id}`, { count: 1 });
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/form-template.js b/app/assets/javascripts/admin/addon/models/form-template.js
index 782b6a8c317..4999210c931 100644
--- a/app/assets/javascripts/admin/addon/models/form-template.js
+++ b/app/assets/javascripts/admin/addon/models/form-template.js
@@ -1,53 +1,51 @@
import RestModel from "discourse/models/rest";
import { ajax } from "discourse/lib/ajax";
-export default class FormTemplate extends RestModel {}
-
-FormTemplate.reopenClass({
- createTemplate(data) {
+export default class FormTemplate extends RestModel {
+ static createTemplate(data) {
return ajax("/admin/customize/form-templates.json", {
type: "POST",
data,
});
- },
+ }
- updateTemplate(id, data) {
+ static updateTemplate(id, data) {
return ajax(`/admin/customize/form-templates/${id}.json`, {
type: "PUT",
data,
});
- },
+ }
- createOrUpdateTemplate(data) {
+ static createOrUpdateTemplate(data) {
if (data.id) {
return this.updateTemplate(data.id, data);
} else {
return this.createTemplate(data);
}
- },
+ }
- deleteTemplate(id) {
+ static deleteTemplate(id) {
return ajax(`/admin/customize/form-templates/${id}.json`, {
type: "DELETE",
});
- },
+ }
- findAll() {
+ static findAll() {
return ajax(`/admin/customize/form-templates.json`).then((model) => {
return model.form_templates.sort((a, b) => a.id - b.id);
});
- },
+ }
- findById(id) {
+ static findById(id) {
return ajax(`/admin/customize/form-templates/${id}.json`).then((model) => {
return model.form_template;
});
- },
+ }
- validateTemplate(data) {
+ static validateTemplate(data) {
return ajax(`/admin/customize/form-templates/preview.json`, {
type: "GET",
data,
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/incoming-email.js b/app/assets/javascripts/admin/addon/models/incoming-email.js
index 8489ae8dd35..2e56e8a8295 100644
--- a/app/assets/javascripts/admin/addon/models/incoming-email.js
+++ b/app/assets/javascripts/admin/addon/models/incoming-email.js
@@ -2,10 +2,8 @@ import AdminUser from "admin/models/admin-user";
import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
-const IncomingEmail = EmberObject.extend({});
-
-IncomingEmail.reopenClass({
- create(attrs) {
+export default class IncomingEmail extends EmberObject {
+ static create(attrs) {
attrs = attrs || {};
if (attrs.user) {
@@ -13,17 +11,17 @@ IncomingEmail.reopenClass({
}
return this._super(attrs);
- },
+ }
- find(id) {
+ static find(id) {
return ajax(`/admin/email/incoming/${id}.json`);
- },
+ }
- findByBounced(id) {
+ static findByBounced(id) {
return ajax(`/admin/email/incoming_from_bounced/${id}.json`);
- },
+ }
- findAll(filter, offset) {
+ static findAll(filter, offset) {
filter = filter || {};
offset = offset || 0;
@@ -35,11 +33,9 @@ IncomingEmail.reopenClass({
}).then((incomings) =>
incomings.map((incoming) => IncomingEmail.create(incoming))
);
- },
+ }
- loadRawEmail(id) {
+ static loadRawEmail(id) {
return ajax(`/admin/email/incoming/${id}/raw.json`);
- },
-});
-
-export default IncomingEmail;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/permalink.js b/app/assets/javascripts/admin/addon/models/permalink.js
index 25a3c90e037..580b111f0ae 100644
--- a/app/assets/javascripts/admin/addon/models/permalink.js
+++ b/app/assets/javascripts/admin/addon/models/permalink.js
@@ -4,7 +4,15 @@ import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-const Permalink = EmberObject.extend({
+export default class Permalink extends EmberObject {
+ static findAll(filter) {
+ return ajax("/admin/permalinks.json", { data: { filter } }).then(function (
+ permalinks
+ ) {
+ return permalinks.map((p) => Permalink.create(p));
+ });
+ }
+
save() {
return ajax("/admin/permalinks.json", {
type: "POST",
@@ -14,33 +22,21 @@ const Permalink = EmberObject.extend({
permalink_type_value: this.permalink_type_value,
},
});
- },
+ }
@discourseComputed("category_id")
category(category_id) {
return Category.findById(category_id);
- },
+ }
@discourseComputed("external_url")
linkIsExternal(external_url) {
return !DiscourseURL.isInternal(external_url);
- },
+ }
destroy() {
return ajax("/admin/permalinks/" + this.id + ".json", {
type: "DELETE",
});
- },
-});
-
-Permalink.reopenClass({
- findAll(filter) {
- return ajax("/admin/permalinks.json", { data: { filter } }).then(function (
- permalinks
- ) {
- return permalinks.map((p) => Permalink.create(p));
- });
- },
-});
-
-export default Permalink;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/report.js b/app/assets/javascripts/admin/addon/models/report.js
index 9cd68dc7987..dd868a00e02 100644
--- a/app/assets/javascripts/admin/addon/models/report.js
+++ b/app/assets/javascripts/admin/addon/models/report.js
@@ -19,12 +19,188 @@ import round from "discourse/lib/round";
// and you want to ensure cache is reset
export const SCHEMA_VERSION = 4;
-const Report = EmberObject.extend({
- average: false,
- percent: false,
- higher_is_better: true,
- description_link: null,
- description: null,
+export default class Report extends EmberObject {
+ static groupingForDatapoints(count) {
+ if (count < DAILY_LIMIT_DAYS) {
+ return "daily";
+ }
+
+ if (count >= DAILY_LIMIT_DAYS && count < WEEKLY_LIMIT_DAYS) {
+ return "weekly";
+ }
+
+ if (count >= WEEKLY_LIMIT_DAYS) {
+ return "monthly";
+ }
+ }
+
+ static unitForDatapoints(count) {
+ if (count >= DAILY_LIMIT_DAYS && count < WEEKLY_LIMIT_DAYS) {
+ return "week";
+ } else if (count >= WEEKLY_LIMIT_DAYS) {
+ return "month";
+ } else {
+ return "day";
+ }
+ }
+
+ static unitForGrouping(grouping) {
+ switch (grouping) {
+ case "monthly":
+ return "month";
+ case "weekly":
+ return "week";
+ default:
+ return "day";
+ }
+ }
+
+ static collapse(model, data, grouping) {
+ grouping = grouping || Report.groupingForDatapoints(data.length);
+
+ if (grouping === "daily") {
+ return data;
+ } else if (grouping === "weekly" || grouping === "monthly") {
+ const isoKind = grouping === "weekly" ? "isoWeek" : "month";
+ const kind = grouping === "weekly" ? "week" : "month";
+ const startMoment = moment(model.start_date, "YYYY-MM-DD");
+
+ let currentIndex = 0;
+ let currentStart = startMoment.clone().startOf(isoKind);
+ let currentEnd = startMoment.clone().endOf(isoKind);
+ const transformedData = [
+ {
+ x: currentStart.format("YYYY-MM-DD"),
+ y: 0,
+ },
+ ];
+
+ let appliedAverage = false;
+ data.forEach((d) => {
+ const date = moment(d.x, "YYYY-MM-DD");
+
+ if (
+ !date.isSame(currentStart) &&
+ !date.isBetween(currentStart, currentEnd)
+ ) {
+ if (model.average) {
+ transformedData[currentIndex].y = applyAverage(
+ transformedData[currentIndex].y,
+ currentStart,
+ currentEnd
+ );
+
+ appliedAverage = true;
+ }
+
+ currentIndex += 1;
+ currentStart = currentStart.add(1, kind).startOf(isoKind);
+ currentEnd = currentEnd.add(1, kind).endOf(isoKind);
+ } else {
+ appliedAverage = false;
+ }
+
+ if (transformedData[currentIndex]) {
+ transformedData[currentIndex].y += d.y;
+ } else {
+ transformedData[currentIndex] = {
+ x: d.x,
+ y: d.y,
+ };
+ }
+ });
+
+ if (model.average && !appliedAverage) {
+ transformedData[currentIndex].y = applyAverage(
+ transformedData[currentIndex].y,
+ currentStart,
+ moment(model.end_date).subtract(1, "day") // remove 1 day as model end date is at 00:00 of next day
+ );
+ }
+
+ return transformedData;
+ }
+
+ // ensure we return something if grouping is unknown
+ return data;
+ }
+
+ static fillMissingDates(report, options = {}) {
+ const dataField = options.dataField || "data";
+ const filledField = options.filledField || "data";
+ const startDate = options.startDate || "start_date";
+ const endDate = options.endDate || "end_date";
+
+ if (Array.isArray(report[dataField])) {
+ const startDateFormatted = moment
+ .utc(report[startDate])
+ .locale("en")
+ .format("YYYY-MM-DD");
+ const endDateFormatted = moment
+ .utc(report[endDate])
+ .locale("en")
+ .format("YYYY-MM-DD");
+
+ if (report.modes[0] === "stacked_chart") {
+ report[filledField] = report[dataField].map((rep) => {
+ return {
+ req: rep.req,
+ label: rep.label,
+ color: rep.color,
+ data: fillMissingDates(
+ JSON.parse(JSON.stringify(rep.data)),
+ startDateFormatted,
+ endDateFormatted
+ ),
+ };
+ });
+ } else {
+ report[filledField] = fillMissingDates(
+ JSON.parse(JSON.stringify(report[dataField])),
+ startDateFormatted,
+ endDateFormatted
+ );
+ }
+ }
+ }
+
+ static find(type, startDate, endDate, categoryId, groupId) {
+ return ajax("/admin/reports/" + type, {
+ data: {
+ start_date: startDate,
+ end_date: endDate,
+ category_id: categoryId,
+ group_id: groupId,
+ },
+ }).then((json) => {
+ // don’t fill for large multi column tables
+ // which are not date based
+ const modes = json.report.modes;
+ if (modes.length !== 1 && modes[0] !== "table") {
+ Report.fillMissingDates(json.report);
+ }
+
+ const model = Report.create({ type });
+ model.setProperties(json.report);
+
+ if (json.report.related_report) {
+ // TODO: fillMissingDates if xaxis is date
+ const related = Report.create({
+ type: json.report.related_report.type,
+ });
+ related.setProperties(json.report.related_report);
+ model.set("relatedReport", related);
+ }
+
+ return model;
+ });
+ }
+
+ average = false;
+ percent = false;
+ higher_is_better = true;
+ description_link = null;
+ description = null;
@discourseComputed("type", "start_date", "end_date")
reportUrl(type, start_date, end_date) {
@@ -35,7 +211,7 @@ const Report = EmberObject.extend({
return getURL(
`/admin/reports/${type}?start_date=${start_date}&end_date=${end_date}`
);
- },
+ }
valueAt(numDaysAgo) {
if (this.data) {
@@ -49,7 +225,7 @@ const Report = EmberObject.extend({
}
}
return 0;
- },
+ }
valueFor(startDaysAgo, endDaysAgo) {
if (this.data) {
@@ -70,46 +246,46 @@ const Report = EmberObject.extend({
}
return round(sum, -2);
}
- },
+ }
@discourseComputed("data", "average")
todayCount() {
return this.valueAt(0);
- },
+ }
@discourseComputed("data", "average")
yesterdayCount() {
return this.valueAt(1);
- },
+ }
@discourseComputed("data", "average")
sevenDaysAgoCount() {
return this.valueAt(7);
- },
+ }
@discourseComputed("data", "average")
thirtyDaysAgoCount() {
return this.valueAt(30);
- },
+ }
@discourseComputed("data", "average")
lastSevenDaysCount() {
return this.averageCount(7, this.valueFor(1, 7));
- },
+ }
@discourseComputed("data", "average")
lastThirtyDaysCount() {
return this.averageCount(30, this.valueFor(1, 30));
- },
+ }
averageCount(count, value) {
return this.average ? value / count : value;
- },
+ }
@discourseComputed("yesterdayCount", "higher_is_better")
yesterdayTrend(yesterdayCount, higherIsBetter) {
return this._computeTrend(this.valueAt(2), yesterdayCount, higherIsBetter);
- },
+ }
@discourseComputed("lastSevenDaysCount", "higher_is_better")
sevenDaysTrend(lastSevenDaysCount, higherIsBetter) {
@@ -118,39 +294,39 @@ const Report = EmberObject.extend({
lastSevenDaysCount,
higherIsBetter
);
- },
+ }
@discourseComputed("data")
currentTotal(data) {
return data.reduce((cur, pair) => cur + pair.y, 0);
- },
+ }
@discourseComputed("data", "currentTotal")
currentAverage(data, total) {
return makeArray(data).length === 0
? 0
: parseFloat((total / parseFloat(data.length)).toFixed(1));
- },
+ }
@discourseComputed("trend", "higher_is_better")
trendIcon(trend, higherIsBetter) {
return this._iconForTrend(trend, higherIsBetter);
- },
+ }
@discourseComputed("sevenDaysTrend", "higher_is_better")
sevenDaysTrendIcon(sevenDaysTrend, higherIsBetter) {
return this._iconForTrend(sevenDaysTrend, higherIsBetter);
- },
+ }
@discourseComputed("thirtyDaysTrend", "higher_is_better")
thirtyDaysTrendIcon(thirtyDaysTrend, higherIsBetter) {
return this._iconForTrend(thirtyDaysTrend, higherIsBetter);
- },
+ }
@discourseComputed("yesterdayTrend", "higher_is_better")
yesterdayTrendIcon(yesterdayTrend, higherIsBetter) {
return this._iconForTrend(yesterdayTrend, higherIsBetter);
- },
+ }
@discourseComputed(
"prev_period",
@@ -161,7 +337,7 @@ const Report = EmberObject.extend({
trend(prev, currentTotal, currentAverage, higherIsBetter) {
const total = this.average ? currentAverage : currentTotal;
return this._computeTrend(prev, total, higherIsBetter);
- },
+ }
@discourseComputed(
"prev30Days",
@@ -180,7 +356,7 @@ const Report = EmberObject.extend({
lastThirtyDaysCount,
higherIsBetter
);
- },
+ }
@discourseComputed("type")
method(type) {
@@ -189,7 +365,7 @@ const Report = EmberObject.extend({
} else {
return "sum";
}
- },
+ }
percentChangeString(val1, val2) {
const change = this._computeChange(val1, val2);
@@ -201,7 +377,7 @@ const Report = EmberObject.extend({
} else {
return change.toFixed(0) + "%";
}
- },
+ }
@discourseComputed("prev_period", "currentTotal", "currentAverage")
trendTitle(prev, currentTotal, currentAverage) {
@@ -224,7 +400,7 @@ const Report = EmberObject.extend({
prev,
current,
});
- },
+ }
changeTitle(valAtT1, valAtT2, prevPeriodString) {
const change = this.percentChangeString(valAtT1, valAtT2);
@@ -234,12 +410,12 @@ const Report = EmberObject.extend({
}
title += `Was ${number(valAtT1)} ${prevPeriodString}.`;
return title;
- },
+ }
@discourseComputed("yesterdayCount")
yesterdayCountTitle(yesterdayCount) {
return this.changeTitle(this.valueAt(2), yesterdayCount, "two days ago");
- },
+ }
@discourseComputed("lastSevenDaysCount")
sevenDaysCountTitle(lastSevenDaysCount) {
@@ -248,12 +424,12 @@ const Report = EmberObject.extend({
lastSevenDaysCount,
"two weeks ago"
);
- },
+ }
@discourseComputed("prev30Days", "prev_period")
canDisplayTrendIcon(prev30Days, prev_period) {
return prev30Days ?? prev_period;
- },
+ }
@discourseComputed("prev30Days", "prev_period", "lastThirtyDaysCount")
thirtyDaysCountTitle(prev30Days, prev_period, lastThirtyDaysCount) {
@@ -262,12 +438,12 @@ const Report = EmberObject.extend({
lastThirtyDaysCount,
"in the previous 30 day period"
);
- },
+ }
@discourseComputed("data")
sortedData(data) {
return this.xAxisIsDate ? data.toArray().reverse() : data.toArray();
- },
+ }
@discourseComputed("data")
xAxisIsDate() {
@@ -275,7 +451,7 @@ const Report = EmberObject.extend({
return false;
}
return this.data && this.data[0].x.match(/\d{4}-\d{1,2}-\d{1,2}/);
- },
+ }
@discourseComputed("labels")
computedLabels(labels) {
@@ -359,7 +535,7 @@ const Report = EmberObject.extend({
},
};
});
- },
+ }
_userLabel(properties, row) {
const username = row[properties.username];
@@ -388,7 +564,7 @@ const Report = EmberObject.extend({
value: username,
formattedValue: username ? formattedValue() : "—",
};
- },
+ }
_topicLabel(properties, row) {
const topicTitle = row[properties.title];
@@ -403,7 +579,7 @@ const Report = EmberObject.extend({
value: topicTitle,
formattedValue: topicTitle ? formattedValue() : "—",
};
- },
+ }
_postLabel(properties, row) {
const postTitle = row[properties.truncated_raw];
@@ -419,21 +595,21 @@ const Report = EmberObject.extend({
? `${escapeExpression(postTitle)}`
: "—",
};
- },
+ }
_secondsLabel(value) {
return {
value: toNumber(value),
formattedValue: durationTiny(value),
};
- },
+ }
_percentLabel(value) {
return {
value: toNumber(value),
formattedValue: value ? `${value}%` : "—",
};
- },
+ }
_numberLabel(value, options = {}) {
const formatNumbers = isEmpty(options.formatNumbers)
@@ -446,21 +622,21 @@ const Report = EmberObject.extend({
value: toNumber(value),
formattedValue: value ? formattedValue() : "—",
};
- },
+ }
_bytesLabel(value) {
return {
value: toNumber(value),
formattedValue: I18n.toHumanSize(value),
};
- },
+ }
_dateLabel(value, date, format = "LL") {
return {
value,
formattedValue: value ? date.format(format) : "—",
};
- },
+ }
_textLabel(value) {
const escaped = escapeExpression(value);
@@ -469,7 +645,7 @@ const Report = EmberObject.extend({
value,
formattedValue: value ? escaped : "—",
};
- },
+ }
_linkLabel(properties, row) {
const property = properties[0];
@@ -484,11 +660,11 @@ const Report = EmberObject.extend({
value,
formattedValue: value ? formattedValue(value, row[properties[1]]) : "—",
};
- },
+ }
_computeChange(valAtT1, valAtT2) {
return ((valAtT2 - valAtT1) / valAtT1) * 100;
- },
+ }
_computeTrend(valAtT1, valAtT2, higherIsBetter) {
const change = this._computeChange(valAtT1, valAtT2);
@@ -504,7 +680,7 @@ const Report = EmberObject.extend({
} else if (change < -2) {
return higherIsBetter ? "trending-down" : "trending-up";
}
- },
+ }
_iconForTrend(trend, higherIsBetter) {
switch (trend) {
@@ -519,8 +695,8 @@ const Report = EmberObject.extend({
default:
return "minus";
}
- },
-});
+ }
+}
export const WEEKLY_LIMIT_DAYS = 365;
export const DAILY_LIMIT_DAYS = 34;
@@ -529,183 +705,3 @@ function applyAverage(value, start, end) {
const count = end.diff(start, "day") + 1; // 1 to include start
return parseFloat((value / count).toFixed(2));
}
-
-Report.reopenClass({
- groupingForDatapoints(count) {
- if (count < DAILY_LIMIT_DAYS) {
- return "daily";
- }
-
- if (count >= DAILY_LIMIT_DAYS && count < WEEKLY_LIMIT_DAYS) {
- return "weekly";
- }
-
- if (count >= WEEKLY_LIMIT_DAYS) {
- return "monthly";
- }
- },
-
- unitForDatapoints(count) {
- if (count >= DAILY_LIMIT_DAYS && count < WEEKLY_LIMIT_DAYS) {
- return "week";
- } else if (count >= WEEKLY_LIMIT_DAYS) {
- return "month";
- } else {
- return "day";
- }
- },
-
- unitForGrouping(grouping) {
- switch (grouping) {
- case "monthly":
- return "month";
- case "weekly":
- return "week";
- default:
- return "day";
- }
- },
-
- collapse(model, data, grouping) {
- grouping = grouping || Report.groupingForDatapoints(data.length);
-
- if (grouping === "daily") {
- return data;
- } else if (grouping === "weekly" || grouping === "monthly") {
- const isoKind = grouping === "weekly" ? "isoWeek" : "month";
- const kind = grouping === "weekly" ? "week" : "month";
- const startMoment = moment(model.start_date, "YYYY-MM-DD");
-
- let currentIndex = 0;
- let currentStart = startMoment.clone().startOf(isoKind);
- let currentEnd = startMoment.clone().endOf(isoKind);
- const transformedData = [
- {
- x: currentStart.format("YYYY-MM-DD"),
- y: 0,
- },
- ];
-
- let appliedAverage = false;
- data.forEach((d) => {
- const date = moment(d.x, "YYYY-MM-DD");
-
- if (
- !date.isSame(currentStart) &&
- !date.isBetween(currentStart, currentEnd)
- ) {
- if (model.average) {
- transformedData[currentIndex].y = applyAverage(
- transformedData[currentIndex].y,
- currentStart,
- currentEnd
- );
-
- appliedAverage = true;
- }
-
- currentIndex += 1;
- currentStart = currentStart.add(1, kind).startOf(isoKind);
- currentEnd = currentEnd.add(1, kind).endOf(isoKind);
- } else {
- appliedAverage = false;
- }
-
- if (transformedData[currentIndex]) {
- transformedData[currentIndex].y += d.y;
- } else {
- transformedData[currentIndex] = {
- x: d.x,
- y: d.y,
- };
- }
- });
-
- if (model.average && !appliedAverage) {
- transformedData[currentIndex].y = applyAverage(
- transformedData[currentIndex].y,
- currentStart,
- moment(model.end_date).subtract(1, "day") // remove 1 day as model end date is at 00:00 of next day
- );
- }
-
- return transformedData;
- }
-
- // ensure we return something if grouping is unknown
- return data;
- },
-
- fillMissingDates(report, options = {}) {
- const dataField = options.dataField || "data";
- const filledField = options.filledField || "data";
- const startDate = options.startDate || "start_date";
- const endDate = options.endDate || "end_date";
-
- if (Array.isArray(report[dataField])) {
- const startDateFormatted = moment
- .utc(report[startDate])
- .locale("en")
- .format("YYYY-MM-DD");
- const endDateFormatted = moment
- .utc(report[endDate])
- .locale("en")
- .format("YYYY-MM-DD");
-
- if (report.modes[0] === "stacked_chart") {
- report[filledField] = report[dataField].map((rep) => {
- return {
- req: rep.req,
- label: rep.label,
- color: rep.color,
- data: fillMissingDates(
- JSON.parse(JSON.stringify(rep.data)),
- startDateFormatted,
- endDateFormatted
- ),
- };
- });
- } else {
- report[filledField] = fillMissingDates(
- JSON.parse(JSON.stringify(report[dataField])),
- startDateFormatted,
- endDateFormatted
- );
- }
- }
- },
-
- find(type, startDate, endDate, categoryId, groupId) {
- return ajax("/admin/reports/" + type, {
- data: {
- start_date: startDate,
- end_date: endDate,
- category_id: categoryId,
- group_id: groupId,
- },
- }).then((json) => {
- // don’t fill for large multi column tables
- // which are not date based
- const modes = json.report.modes;
- if (modes.length !== 1 && modes[0] !== "table") {
- Report.fillMissingDates(json.report);
- }
-
- const model = Report.create({ type });
- model.setProperties(json.report);
-
- if (json.report.related_report) {
- // TODO: fillMissingDates if xaxis is date
- const related = Report.create({
- type: json.report.related_report.type,
- });
- related.setProperties(json.report.related_report);
- model.set("relatedReport", related);
- }
-
- return model;
- });
- },
-});
-
-export default Report;
diff --git a/app/assets/javascripts/admin/addon/models/screened-email.js b/app/assets/javascripts/admin/addon/models/screened-email.js
index 62e985949df..8d7a3161ad8 100644
--- a/app/assets/javascripts/admin/addon/models/screened-email.js
+++ b/app/assets/javascripts/admin/addon/models/screened-email.js
@@ -3,21 +3,8 @@ import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-const ScreenedEmail = EmberObject.extend({
- @discourseComputed("action")
- actionName(action) {
- return I18n.t("admin.logs.screened_actions." + action);
- },
-
- clearBlock() {
- return ajax("/admin/logs/screened_emails/" + this.id, {
- type: "DELETE",
- });
- },
-});
-
-ScreenedEmail.reopenClass({
- findAll() {
+export default class ScreenedEmail extends EmberObject {
+ static findAll() {
return ajax("/admin/logs/screened_emails.json").then(function (
screened_emails
) {
@@ -25,7 +12,16 @@ ScreenedEmail.reopenClass({
return ScreenedEmail.create(b);
});
});
- },
-});
+ }
-export default ScreenedEmail;
+ @discourseComputed("action")
+ actionName(action) {
+ return I18n.t("admin.logs.screened_actions." + action);
+ }
+
+ clearBlock() {
+ return ajax("/admin/logs/screened_emails/" + this.id, {
+ type: "DELETE",
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/screened-ip-address.js b/app/assets/javascripts/admin/addon/models/screened-ip-address.js
index 0fe7578f89f..87979087aaa 100644
--- a/app/assets/javascripts/admin/addon/models/screened-ip-address.js
+++ b/app/assets/javascripts/admin/addon/models/screened-ip-address.js
@@ -1,21 +1,28 @@
+import { equal } from "@ember/object/computed";
import EmberObject from "@ember/object";
import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-import { equal } from "@ember/object/computed";
-const ScreenedIpAddress = EmberObject.extend({
+export default class ScreenedIpAddress extends EmberObject {
+ static findAll(filter) {
+ return ajax("/admin/logs/screened_ip_addresses.json", {
+ data: { filter },
+ }).then((screened_ips) =>
+ screened_ips.map((b) => ScreenedIpAddress.create(b))
+ );
+ }
+
+ @equal("action_name", "block") isBlocked;
@discourseComputed("action_name")
actionName(actionName) {
return I18n.t(`admin.logs.screened_ips.actions.${actionName}`);
- },
-
- isBlocked: equal("action_name", "block"),
+ }
@discourseComputed("ip_address")
isRange(ipAddress) {
return ipAddress.indexOf("/") > 0;
- },
+ }
save() {
return ajax(
@@ -30,23 +37,11 @@ const ScreenedIpAddress = EmberObject.extend({
},
}
);
- },
+ }
destroy() {
return ajax("/admin/logs/screened_ip_addresses/" + this.id + ".json", {
type: "DELETE",
});
- },
-});
-
-ScreenedIpAddress.reopenClass({
- findAll(filter) {
- return ajax("/admin/logs/screened_ip_addresses.json", {
- data: { filter },
- }).then((screened_ips) =>
- screened_ips.map((b) => ScreenedIpAddress.create(b))
- );
- },
-});
-
-export default ScreenedIpAddress;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/screened-url.js b/app/assets/javascripts/admin/addon/models/screened-url.js
index 9a0d4e1b737..3d2c5f97941 100644
--- a/app/assets/javascripts/admin/addon/models/screened-url.js
+++ b/app/assets/javascripts/admin/addon/models/screened-url.js
@@ -3,15 +3,8 @@ import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-const ScreenedUrl = EmberObject.extend({
- @discourseComputed("action")
- actionName(action) {
- return I18n.t("admin.logs.screened_actions." + action);
- },
-});
-
-ScreenedUrl.reopenClass({
- findAll() {
+export default class ScreenedUrl extends EmberObject {
+ static findAll() {
return ajax("/admin/logs/screened_urls.json").then(function (
screened_urls
) {
@@ -19,7 +12,10 @@ ScreenedUrl.reopenClass({
return ScreenedUrl.create(b);
});
});
- },
-});
+ }
-export default ScreenedUrl;
+ @discourseComputed("action")
+ actionName(action) {
+ return I18n.t("admin.logs.screened_actions." + action);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/site-setting.js b/app/assets/javascripts/admin/addon/models/site-setting.js
index 49ed58366e1..6cd7852834e 100644
--- a/app/assets/javascripts/admin/addon/models/site-setting.js
+++ b/app/assets/javascripts/admin/addon/models/site-setting.js
@@ -4,22 +4,8 @@ import Setting from "admin/mixins/setting-object";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-const SiteSetting = EmberObject.extend(Setting, {
- @discourseComputed("setting")
- staffLogFilter(setting) {
- if (!setting) {
- return;
- }
-
- return {
- subject: setting,
- action_name: "change_site_setting",
- };
- },
-});
-
-SiteSetting.reopenClass({
- findAll() {
+export default class SiteSetting extends EmberObject.extend(Setting) {
+ static findAll() {
return ajax("/admin/site_settings").then(function (settings) {
// Group the results by category
const categories = {};
@@ -38,9 +24,9 @@ SiteSetting.reopenClass({
};
});
});
- },
+ }
- update(key, value, opts = {}) {
+ static update(key, value, opts = {}) {
const data = {};
data[key] = value;
@@ -49,7 +35,17 @@ SiteSetting.reopenClass({
}
return ajax(`/admin/site_settings/${key}`, { type: "PUT", data });
- },
-});
+ }
-export default SiteSetting;
+ @discourseComputed("setting")
+ staffLogFilter(setting) {
+ if (!setting) {
+ return;
+ }
+
+ return {
+ subject: setting,
+ action_name: "change_site_setting",
+ };
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/site-text.js b/app/assets/javascripts/admin/addon/models/site-text.js
index c25a5b30a00..916030b8d3a 100644
--- a/app/assets/javascripts/admin/addon/models/site-text.js
+++ b/app/assets/javascripts/admin/addon/models/site-text.js
@@ -2,10 +2,10 @@ import RestModel from "discourse/models/rest";
import { ajax } from "discourse/lib/ajax";
import { getProperties } from "@ember/object";
-export default RestModel.extend({
+export default class SiteText extends RestModel {
revert(locale) {
return ajax(`/admin/customize/site_texts/${this.id}?locale=${locale}`, {
type: "DELETE",
}).then((result) => getProperties(result.site_text, "value", "can_revert"));
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/staff-action-log.js b/app/assets/javascripts/admin/addon/models/staff-action-log.js
index 70d86c41e77..4eb7864dd44 100644
--- a/app/assets/javascripts/admin/addon/models/staff-action-log.js
+++ b/app/assets/javascripts/admin/addon/models/staff-action-log.js
@@ -11,13 +11,36 @@ function format(label, value, escape = true) {
: "";
}
-const StaffActionLog = RestModel.extend({
- showFullDetails: false,
+export default class StaffActionLog extends RestModel {
+ static munge(json) {
+ if (json.acting_user) {
+ json.acting_user = AdminUser.create(json.acting_user);
+ }
+ if (json.target_user) {
+ json.target_user = AdminUser.create(json.target_user);
+ }
+ return json;
+ }
+
+ static findAll(data) {
+ return ajax("/admin/logs/staff_action_logs.json", { data }).then(
+ (result) => {
+ return {
+ staff_action_logs: result.staff_action_logs.map((s) =>
+ StaffActionLog.create(s)
+ ),
+ user_history_actions: result.user_history_actions,
+ };
+ }
+ );
+ }
+
+ showFullDetails = false;
@discourseComputed("action_name")
actionName(actionName) {
return I18n.t(`admin.logs.staff_actions.actions.${actionName}`);
- },
+ }
@discourseComputed(
"email",
@@ -72,42 +95,15 @@ const StaffActionLog = RestModel.extend({
const formatted = lines.filter((l) => l.length > 0).join("
");
return formatted.length > 0 ? formatted + "
" : "";
- },
+ }
@discourseComputed("details")
useModalForDetails(details) {
return details && details.length > 100;
- },
+ }
@discourseComputed("action_name")
useCustomModalForDetails(actionName) {
return ["change_theme", "delete_theme"].includes(actionName);
- },
-});
-
-StaffActionLog.reopenClass({
- munge(json) {
- if (json.acting_user) {
- json.acting_user = AdminUser.create(json.acting_user);
- }
- if (json.target_user) {
- json.target_user = AdminUser.create(json.target_user);
- }
- return json;
- },
-
- findAll(data) {
- return ajax("/admin/logs/staff_action_logs.json", { data }).then(
- (result) => {
- return {
- staff_action_logs: result.staff_action_logs.map((s) =>
- StaffActionLog.create(s)
- ),
- user_history_actions: result.user_history_actions,
- };
- }
- );
- },
-});
-
-export default StaffActionLog;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/theme-settings.js b/app/assets/javascripts/admin/addon/models/theme-settings.js
index d91c3e583ef..f61da7c2c0e 100644
--- a/app/assets/javascripts/admin/addon/models/theme-settings.js
+++ b/app/assets/javascripts/admin/addon/models/theme-settings.js
@@ -1,4 +1,4 @@
import EmberObject from "@ember/object";
import Setting from "admin/mixins/setting-object";
-export default EmberObject.extend(Setting, {});
+export default class ThemeSettings extends EmberObject.extend(Setting) {}
diff --git a/app/assets/javascripts/admin/addon/models/theme.js b/app/assets/javascripts/admin/addon/models/theme.js
index a7ac122c04c..a4b7d6b64b5 100644
--- a/app/assets/javascripts/admin/addon/models/theme.js
+++ b/app/assets/javascripts/admin/addon/models/theme.js
@@ -13,11 +13,13 @@ export const THEMES = "themes";
export const COMPONENTS = "components";
const SETTINGS_TYPE_ID = 5;
-const Theme = RestModel.extend({
- isActive: or("default", "user_selectable"),
- isPendingUpdates: gt("remote_theme.commits_behind", 0),
- hasEditedFields: gt("editedFields.length", 0),
- hasParents: gt("parent_themes.length", 0),
+class Theme extends RestModel {
+ @or("default", "user_selectable") isActive;
+ @gt("remote_theme.commits_behind", 0) isPendingUpdates;
+ @gt("editedFields.length", 0) hasEditedFields;
+ @gt("parent_themes.length", 0) hasParents;
+
+ changed = false;
@discourseComputed("theme_fields.[]")
targets() {
@@ -45,7 +47,7 @@ const Theme = RestModel.extend({
target["error"] = this.hasError(target.name);
return target;
});
- },
+ }
@discourseComputed("theme_fields.[]")
fieldNames() {
@@ -84,7 +86,7 @@ const Theme = RestModel.extend({
],
extra_scss: scss_fields,
};
- },
+ }
@discourseComputed(
"fieldNames",
@@ -118,7 +120,7 @@ const Theme = RestModel.extend({
});
});
return hash;
- },
+ }
@discourseComputed("theme_fields")
themeFields(fields) {
@@ -134,7 +136,7 @@ const Theme = RestModel.extend({
}
});
return hash;
- },
+ }
@discourseComputed("theme_fields", "theme_fields.[]")
uploads(fields) {
@@ -144,32 +146,32 @@ const Theme = RestModel.extend({
return fields.filter(
(f) => f.target === "common" && f.type_id === THEME_UPLOAD_VAR
);
- },
+ }
@discourseComputed("theme_fields", "theme_fields.@each.error")
isBroken(fields) {
return (
fields && fields.any((field) => field.error && field.error.length > 0)
);
- },
+ }
@discourseComputed("theme_fields.[]")
editedFields(fields) {
return fields.filter(
(field) => !isBlank(field.value) && field.type_id !== SETTINGS_TYPE_ID
);
- },
+ }
@discourseComputed("remote_theme.last_error_text")
remoteError(errorText) {
if (errorText && errorText.length > 0) {
return errorText;
}
- },
+ }
getKey(field) {
return `${field.target} ${field.name}`;
- },
+ }
hasEdited(target, name) {
if (name) {
@@ -180,27 +182,27 @@ const Theme = RestModel.extend({
(field) => field.target === target && !isEmpty(field.value)
);
}
- },
+ }
hasError(target, name) {
return this.theme_fields
.filter((f) => f.target === target && (!name || name === f.name))
.any((f) => f.error);
- },
+ }
getError(target, name) {
let themeFields = this.themeFields;
let key = this.getKey({ target, name });
let field = themeFields[key];
return field ? field.error : "";
- },
+ }
getField(target, name) {
let themeFields = this.themeFields;
let key = this.getKey({ target, name });
let field = themeFields[key];
return field ? field.value : "";
- },
+ }
removeField(field) {
this.set("changed", true);
@@ -209,7 +211,7 @@ const Theme = RestModel.extend({
field.value = null;
return this.saveChanges("theme_fields");
- },
+ }
setField(target, name, value, upload_id, type_id) {
this.set("changed", true);
@@ -249,25 +251,25 @@ const Theme = RestModel.extend({
this.notifyPropertyChange("theme_fields.[]");
}
}
- },
+ }
@discourseComputed("childThemes.[]")
child_theme_ids(childThemes) {
if (childThemes) {
return childThemes.map((theme) => get(theme, "id"));
}
- },
+ }
@discourseComputed("recentlyInstalled", "component", "hasParents")
warnUnassignedComponent(recent, component, hasParents) {
return recent && component && !hasParents;
- },
+ }
removeChildTheme(theme) {
const childThemes = this.childThemes;
childThemes.removeObject(theme);
return this.saveChanges("child_theme_ids");
- },
+ }
addChildTheme(theme) {
let childThemes = this.childThemes;
@@ -278,7 +280,7 @@ const Theme = RestModel.extend({
childThemes.removeObject(theme);
childThemes.pushObject(theme);
return this.saveChanges("child_theme_ids");
- },
+ }
addParentTheme(theme) {
let parentThemes = this.parentThemes;
@@ -287,38 +289,36 @@ const Theme = RestModel.extend({
this.set("parentThemes", parentThemes);
}
parentThemes.addObject(theme);
- },
+ }
checkForUpdates() {
return this.save({ remote_check: true }).then(() =>
this.set("changed", false)
);
- },
+ }
updateToLatest() {
return this.save({ remote_update: true }).then(() =>
this.set("changed", false)
);
- },
-
- changed: false,
+ }
saveChanges() {
const hash = this.getProperties.apply(this, arguments);
return this.save(hash)
.finally(() => this.set("changed", false))
.catch(popupAjaxError);
- },
+ }
saveSettings(name, value) {
const settings = {};
settings[name] = value;
return this.save({ settings });
- },
+ }
saveTranslation(name, value) {
return this.save({ translations: { [name]: value } });
- },
-});
+ }
+}
export default Theme;
diff --git a/app/assets/javascripts/admin/addon/models/tl3-requirements.js b/app/assets/javascripts/admin/addon/models/tl3-requirements.js
index 920d6e5f665..43a41362369 100644
--- a/app/assets/javascripts/admin/addon/models/tl3-requirements.js
+++ b/app/assets/javascripts/admin/addon/models/tl3-requirements.js
@@ -1,21 +1,21 @@
import EmberObject from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
-export default EmberObject.extend({
+export default class Tl3Requirements extends EmberObject {
@discourseComputed("days_visited", "time_period")
days_visited_percent(daysVisited, timePeriod) {
return Math.round((daysVisited * 100) / timePeriod);
- },
+ }
@discourseComputed("min_days_visited", "time_period")
min_days_visited_percent(minDaysVisited, timePeriod) {
return Math.round((minDaysVisited * 100) / timePeriod);
- },
+ }
@discourseComputed("num_topics_replied_to", "min_topics_replied_to")
capped_topics_replied_to(numReplied, minReplied) {
return numReplied > minReplied;
- },
+ }
@discourseComputed(
"days_visited",
@@ -71,5 +71,5 @@ export default EmberObject.extend({
silenced: this.get("penalty_counts.silenced") === 0,
suspended: this.get("penalty_counts.suspended") === 0,
};
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/user-field.js b/app/assets/javascripts/admin/addon/models/user-field.js
index 53b92a63fd9..5a8bdea1832 100644
--- a/app/assets/javascripts/admin/addon/models/user-field.js
+++ b/app/assets/javascripts/admin/addon/models/user-field.js
@@ -2,14 +2,8 @@ import EmberObject from "@ember/object";
import RestModel from "discourse/models/rest";
import { i18n } from "discourse/lib/computed";
-const UserField = RestModel.extend();
-
-const UserFieldType = EmberObject.extend({
- name: i18n("id", "admin.user_fields.field_types.%@"),
-});
-
-UserField.reopenClass({
- fieldTypes() {
+export default class UserField extends RestModel {
+ static fieldTypes() {
if (!this._fieldTypes) {
this._fieldTypes = [
UserFieldType.create({ id: "text" }),
@@ -20,11 +14,13 @@ UserField.reopenClass({
}
return this._fieldTypes;
- },
+ }
- fieldTypeById(id) {
+ static fieldTypeById(id) {
return this.fieldTypes().findBy("id", id);
- },
-});
+ }
+}
-export default UserField;
+class UserFieldType extends EmberObject {
+ @i18n("id", "admin.user_fields.field_types.%@") name;
+}
diff --git a/app/assets/javascripts/admin/addon/models/version-check.js b/app/assets/javascripts/admin/addon/models/version-check.js
index edf6ad5e0e6..baf029c3c47 100644
--- a/app/assets/javascripts/admin/addon/models/version-check.js
+++ b/app/assets/javascripts/admin/addon/models/version-check.js
@@ -2,43 +2,39 @@ import EmberObject from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-const VersionCheck = EmberObject.extend({
+export default class VersionCheck extends EmberObject {
+ static find() {
+ return ajax("/admin/version_check").then((json) =>
+ VersionCheck.create(json)
+ );
+ }
+
@discourseComputed("updated_at")
noCheckPerformed(updatedAt) {
return updatedAt === null;
- },
+ }
@discourseComputed("missing_versions_count")
upToDate(missingVersionsCount) {
return missingVersionsCount === 0 || missingVersionsCount === null;
- },
+ }
@discourseComputed("missing_versions_count")
behindByOneVersion(missingVersionsCount) {
return missingVersionsCount === 1;
- },
+ }
@discourseComputed("installed_sha")
gitLink(installedSHA) {
if (installedSHA) {
return `https://github.com/discourse/discourse/commits/${installedSHA}`;
}
- },
+ }
@discourseComputed("installed_sha")
shortSha(installedSHA) {
if (installedSHA) {
return installedSHA.slice(0, 10);
}
- },
-});
-
-VersionCheck.reopenClass({
- find() {
- return ajax("/admin/version_check").then((json) =>
- VersionCheck.create(json)
- );
- },
-});
-
-export default VersionCheck;
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/watched-word.js b/app/assets/javascripts/admin/addon/models/watched-word.js
index ceb9317f369..a6de62cc9db 100644
--- a/app/assets/javascripts/admin/addon/models/watched-word.js
+++ b/app/assets/javascripts/admin/addon/models/watched-word.js
@@ -2,34 +2,8 @@ import EmberObject from "@ember/object";
import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
-const WatchedWord = EmberObject.extend({
- save() {
- return ajax(
- "/admin/customize/watched_words" +
- (this.id ? "/" + this.id : "") +
- ".json",
- {
- type: this.id ? "PUT" : "POST",
- data: {
- word: this.word,
- replacement: this.replacement,
- action_key: this.action,
- case_sensitive: this.isCaseSensitive,
- },
- dataType: "json",
- }
- );
- },
-
- destroy() {
- return ajax("/admin/customize/watched_words/" + this.id + ".json", {
- type: "DELETE",
- });
- },
-});
-
-WatchedWord.reopenClass({
- findAll() {
+export default class WatchedWord extends EmberObject {
+ static findAll() {
return ajax("/admin/customize/watched_words.json").then((list) => {
const actions = {};
@@ -50,7 +24,29 @@ WatchedWord.reopenClass({
});
});
});
- },
-});
+ }
-export default WatchedWord;
+ save() {
+ return ajax(
+ "/admin/customize/watched_words" +
+ (this.id ? "/" + this.id : "") +
+ ".json",
+ {
+ type: this.id ? "PUT" : "POST",
+ data: {
+ word: this.word,
+ replacement: this.replacement,
+ action_key: this.action,
+ case_sensitive: this.isCaseSensitive,
+ },
+ dataType: "json",
+ }
+ );
+ }
+
+ destroy() {
+ return ajax("/admin/customize/watched_words/" + this.id + ".json", {
+ type: "DELETE",
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/models/web-hook.js b/app/assets/javascripts/admin/addon/models/web-hook.js
index 500311bec80..c955d67ae98 100644
--- a/app/assets/javascripts/admin/addon/models/web-hook.js
+++ b/app/assets/javascripts/admin/addon/models/web-hook.js
@@ -1,33 +1,34 @@
-import discourseComputed, { observes } from "discourse-common/utils/decorators";
+import { computed } from "@ember/object";
+import discourseComputed from "discourse-common/utils/decorators";
+import { observes } from "@ember-decorators/object";
import Category from "discourse/models/category";
import Group from "discourse/models/group";
import RestModel from "discourse/models/rest";
import Site from "discourse/models/site";
import { isEmpty } from "@ember/utils";
-export default RestModel.extend({
- content_type: 1, // json
- last_delivery_status: 1, // inactive
- wildcard_web_hook: false,
- verify_certificate: true,
- active: false,
- web_hook_event_types: null,
- groupsFilterInName: null,
+export default class WebHook extends RestModel {
+ content_type = 1; // json
+ last_delivery_status = 1; // inactive
+ wildcard_web_hook = false;
+ verify_certificate = true;
+ active = false;
+ web_hook_event_types = null;
+ groupsFilterInName = null;
- @discourseComputed("wildcard_web_hook")
- webhookType: {
- get(wildcard) {
- return wildcard ? "wildcard" : "individual";
- },
- set(value) {
- this.set("wildcard_web_hook", value === "wildcard");
- },
- },
+ @computed("wildcard_web_hook")
+ get wildcard() {
+ return this.wildcard_web_hook ? "wildcard" : "individual";
+ }
+
+ set wildcard(value) {
+ this.set("wildcard_web_hook", value === "wildcard");
+ }
@discourseComputed("category_ids")
categories(categoryIds) {
return Category.findByIds(categoryIds);
- },
+ }
@observes("group_ids")
updateGroupsFilter() {
@@ -41,11 +42,11 @@ export default RestModel.extend({
return groupNames;
}, [])
);
- },
+ }
groupFinder(term) {
return Group.findAll({ term, ignore_automatic: false });
- },
+ }
@discourseComputed("wildcard_web_hook", "web_hook_event_types.[]")
description(isWildcardWebHook, types) {
@@ -57,7 +58,7 @@ export default RestModel.extend({
});
return isWildcardWebHook ? "*" : desc;
- },
+ }
createProperties() {
const types = this.web_hook_event_types;
@@ -92,9 +93,9 @@ export default RestModel.extend({
return groupIds;
}, []),
};
- },
+ }
updateProperties() {
return this.createProperties();
- },
-});
+ }
+}