DEV: Update admin modal controllers to native class syntax (#20685)
This commit was generated using the ember-native-class-codemod along with a handful of manual updates
This commit is contained in:
parent
62bbdd25ab
commit
c190994046
|
@ -1,6 +1,8 @@
|
|||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import { and, not } from "@ember/object/computed";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { observes } from "@ember-decorators/object";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
|
@ -53,18 +55,20 @@ const SCSS_VARIABLE_NAMES = [
|
|||
"love-low",
|
||||
];
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
adminCustomizeThemesShow: controller(),
|
||||
export default class AdminAddUploadController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@controller adminCustomizeThemesShow;
|
||||
|
||||
uploadUrl: "/admin/themes/upload_asset",
|
||||
uploadUrl = "/admin/themes/upload_asset";
|
||||
|
||||
@and("nameValid", "fileSelected") enabled;
|
||||
@not("enabled") disabled;
|
||||
|
||||
onShow() {
|
||||
this.set("name", null);
|
||||
this.set("fileSelected", false);
|
||||
},
|
||||
|
||||
enabled: and("nameValid", "fileSelected"),
|
||||
disabled: not("enabled"),
|
||||
}
|
||||
|
||||
@discourseComputed("name", "adminCustomizeThemesShow.model.theme_fields")
|
||||
errorMessage(name, themeFields) {
|
||||
|
@ -89,54 +93,54 @@ export default Controller.extend(ModalFunctionality, {
|
|||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("errorMessage")
|
||||
nameValid(errorMessage) {
|
||||
return null === errorMessage;
|
||||
},
|
||||
}
|
||||
|
||||
@observes("name")
|
||||
uploadChanged() {
|
||||
const file = $("#file-input")[0];
|
||||
this.set("fileSelected", file && file.files[0]);
|
||||
},
|
||||
}
|
||||
|
||||
actions: {
|
||||
updateName() {
|
||||
let name = this.name;
|
||||
if (isEmpty(name)) {
|
||||
name = $("#file-input")[0].files[0].name;
|
||||
this.set("name", name.split(".")[0]);
|
||||
}
|
||||
this.uploadChanged();
|
||||
},
|
||||
@action
|
||||
updateName() {
|
||||
let name = this.name;
|
||||
if (isEmpty(name)) {
|
||||
name = $("#file-input")[0].files[0].name;
|
||||
this.set("name", name.split(".")[0]);
|
||||
}
|
||||
this.uploadChanged();
|
||||
}
|
||||
|
||||
upload() {
|
||||
const file = $("#file-input")[0].files[0];
|
||||
@action
|
||||
upload() {
|
||||
const file = $("#file-input")[0].files[0];
|
||||
|
||||
const options = {
|
||||
type: "POST",
|
||||
processData: false,
|
||||
contentType: false,
|
||||
data: new FormData(),
|
||||
};
|
||||
const options = {
|
||||
type: "POST",
|
||||
processData: false,
|
||||
contentType: false,
|
||||
data: new FormData(),
|
||||
};
|
||||
|
||||
options.data.append("file", file);
|
||||
options.data.append("file", file);
|
||||
|
||||
ajax(this.uploadUrl, options)
|
||||
.then((result) => {
|
||||
const upload = {
|
||||
upload_id: result.upload_id,
|
||||
name: this.name,
|
||||
original_filename: file.name,
|
||||
};
|
||||
this.adminCustomizeThemesShow.send("addUpload", upload);
|
||||
this.send("closeModal");
|
||||
})
|
||||
.catch((e) => {
|
||||
popupAjaxError(e);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
ajax(this.uploadUrl, options)
|
||||
.then((result) => {
|
||||
const upload = {
|
||||
upload_id: result.upload_id,
|
||||
name: this.name,
|
||||
original_filename: file.name,
|
||||
};
|
||||
this.adminCustomizeThemesShow.send("addUpload", upload);
|
||||
this.send("closeModal");
|
||||
})
|
||||
.catch((e) => {
|
||||
popupAjaxError(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,39 +4,12 @@ import I18n from "I18n";
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
|
||||
export default Controller.extend({
|
||||
sample: alias("model.sample"),
|
||||
errors: alias("model.errors"),
|
||||
count: alias("model.grant_count"),
|
||||
export default class AdminBadgePreviewController extends Controller {
|
||||
@alias("model.sample") sample;
|
||||
@alias("model.errors") errors;
|
||||
@alias("model.grant_count") count;
|
||||
|
||||
@discourseComputed("count", "sample.length")
|
||||
countWarning(count, sampleLength) {
|
||||
if (count <= 10) {
|
||||
return sampleLength !== count;
|
||||
} else {
|
||||
return sampleLength !== 10;
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("model.query_plan")
|
||||
hasQueryPlan(queryPlan) {
|
||||
return !!queryPlan;
|
||||
},
|
||||
|
||||
@discourseComputed("model.query_plan")
|
||||
queryPlanHtml(queryPlan) {
|
||||
let output = `<pre class="badge-query-plan">`;
|
||||
|
||||
queryPlan.forEach((linehash) => {
|
||||
output += escapeExpression(linehash["QUERY PLAN"]);
|
||||
output += "<br>";
|
||||
});
|
||||
|
||||
output += "</pre>";
|
||||
return output;
|
||||
},
|
||||
|
||||
processedSample: map("model.sample", (grant) => {
|
||||
@map("model.sample", (grant) => {
|
||||
let i18nKey = "admin.badges.preview.grant.with";
|
||||
const i18nParams = { username: escapeExpression(grant.username) };
|
||||
|
||||
|
@ -55,5 +28,33 @@ export default Controller.extend({
|
|||
}
|
||||
|
||||
return I18n.t(i18nKey, i18nParams);
|
||||
}),
|
||||
});
|
||||
})
|
||||
processedSample;
|
||||
|
||||
@discourseComputed("count", "sample.length")
|
||||
countWarning(count, sampleLength) {
|
||||
if (count <= 10) {
|
||||
return sampleLength !== count;
|
||||
} else {
|
||||
return sampleLength !== 10;
|
||||
}
|
||||
}
|
||||
|
||||
@discourseComputed("model.query_plan")
|
||||
hasQueryPlan(queryPlan) {
|
||||
return !!queryPlan;
|
||||
}
|
||||
|
||||
@discourseComputed("model.query_plan")
|
||||
queryPlanHtml(queryPlan) {
|
||||
let output = `<pre class="badge-query-plan">`;
|
||||
|
||||
queryPlan.forEach((linehash) => {
|
||||
output += escapeExpression(linehash["QUERY PLAN"]);
|
||||
output += "<br>";
|
||||
});
|
||||
|
||||
output += "</pre>";
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
import { action } from "@ember/object";
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
adminCustomizeColors: controller(),
|
||||
export default class AdminColorSchemeSelectBaseController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@controller adminCustomizeColors;
|
||||
|
||||
selectedBaseThemeId: null,
|
||||
selectedBaseThemeId = null;
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
super.init(...arguments);
|
||||
|
||||
const defaultScheme = this.get(
|
||||
"adminCustomizeColors.baseColorSchemes.0.base_scheme_id"
|
||||
);
|
||||
this.set("selectedBaseThemeId", defaultScheme);
|
||||
},
|
||||
}
|
||||
|
||||
actions: {
|
||||
selectBase() {
|
||||
this.adminCustomizeColors.send(
|
||||
"newColorSchemeWithBase",
|
||||
this.selectedBaseThemeId
|
||||
);
|
||||
this.send("closeModal");
|
||||
},
|
||||
},
|
||||
});
|
||||
@action
|
||||
selectBase() {
|
||||
this.adminCustomizeColors.send(
|
||||
"newColorSchemeWithBase",
|
||||
this.selectedBaseThemeId
|
||||
);
|
||||
this.send("closeModal");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import { alias } from "@ember/object/computed";
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { action } from "@ember/object";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
adminUserIndex: controller(),
|
||||
username: alias("model.username"),
|
||||
postCount: alias("model.post_count"),
|
||||
export default class AdminDeletePostsConfirmationController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@controller adminUserIndex;
|
||||
|
||||
@alias("model.username") username;
|
||||
@alias("model.post_count") postCount;
|
||||
|
||||
onShow() {
|
||||
this.set("value", null);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("username", "postCount")
|
||||
text(username, postCount) {
|
||||
|
@ -20,27 +23,27 @@ export default Controller.extend(ModalFunctionality, {
|
|||
username,
|
||||
postCount,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("username")
|
||||
deleteButtonText(username) {
|
||||
return I18n.t(`admin.user.delete_posts.confirmation.delete`, {
|
||||
username,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("value", "text")
|
||||
deleteDisabled(value, text) {
|
||||
return !value || text !== value;
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
confirm() {
|
||||
this.adminUserIndex.send("deleteAllPosts");
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
close() {
|
||||
this.send("closeModal");
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import Controller from "@ember/controller";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
deletedPercentage: 0,
|
||||
});
|
||||
export default class AdminDeleteUserPostsProgressController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
deletedPercentage = 0;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { A } from "@ember/array";
|
||||
import Controller from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
dialog: service(),
|
||||
export default class AdminEditBadgeGroupingsController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@service dialog;
|
||||
|
||||
@observes("model")
|
||||
modelChanged() {
|
||||
|
@ -22,7 +25,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
}
|
||||
|
||||
this.set("workingCopy", copy);
|
||||
},
|
||||
}
|
||||
|
||||
moveItem(item, delta) {
|
||||
const copy = this.workingCopy;
|
||||
|
@ -33,55 +36,68 @@ export default Controller.extend(ModalFunctionality, {
|
|||
|
||||
copy.removeAt(index);
|
||||
copy.insertAt(index + delta, item);
|
||||
},
|
||||
}
|
||||
|
||||
actions: {
|
||||
up(item) {
|
||||
this.moveItem(item, -1);
|
||||
},
|
||||
down(item) {
|
||||
this.moveItem(item, 1);
|
||||
},
|
||||
delete(item) {
|
||||
this.workingCopy.removeObject(item);
|
||||
},
|
||||
cancel() {
|
||||
this.setProperties({ model: null, workingCopy: null });
|
||||
this.send("closeModal");
|
||||
},
|
||||
edit(item) {
|
||||
item.set("editing", true);
|
||||
},
|
||||
save(item) {
|
||||
item.set("editing", false);
|
||||
},
|
||||
add() {
|
||||
const obj = this.store.createRecord("badge-grouping", {
|
||||
editing: true,
|
||||
name: I18n.t("admin.badges.badge_grouping"),
|
||||
});
|
||||
this.workingCopy.pushObject(obj);
|
||||
},
|
||||
saveAll() {
|
||||
let items = this.workingCopy;
|
||||
const groupIds = items.map((i) => i.get("id") || -1);
|
||||
const names = items.map((i) => i.get("name"));
|
||||
@action
|
||||
up(item) {
|
||||
this.moveItem(item, -1);
|
||||
}
|
||||
|
||||
ajax("/admin/badges/badge_groupings", {
|
||||
data: { ids: groupIds, names },
|
||||
type: "POST",
|
||||
}).then(
|
||||
(data) => {
|
||||
items = this.model;
|
||||
items.clear();
|
||||
data.badge_groupings.forEach((g) => {
|
||||
items.pushObject(this.store.createRecord("badge-grouping", g));
|
||||
});
|
||||
this.setProperties({ model: null, workingCopy: null });
|
||||
this.send("closeModal");
|
||||
},
|
||||
() => this.dialog.alert(I18n.t("generic_error"))
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
@action
|
||||
down(item) {
|
||||
this.moveItem(item, 1);
|
||||
}
|
||||
|
||||
@action
|
||||
delete(item) {
|
||||
this.workingCopy.removeObject(item);
|
||||
}
|
||||
|
||||
@action
|
||||
cancel() {
|
||||
this.setProperties({ model: null, workingCopy: null });
|
||||
this.send("closeModal");
|
||||
}
|
||||
|
||||
@action
|
||||
edit(item) {
|
||||
item.set("editing", true);
|
||||
}
|
||||
|
||||
@action
|
||||
save(item) {
|
||||
item.set("editing", false);
|
||||
}
|
||||
|
||||
@action
|
||||
add() {
|
||||
const obj = this.store.createRecord("badge-grouping", {
|
||||
editing: true,
|
||||
name: I18n.t("admin.badges.badge_grouping"),
|
||||
});
|
||||
this.workingCopy.pushObject(obj);
|
||||
}
|
||||
|
||||
@action
|
||||
saveAll() {
|
||||
let items = this.workingCopy;
|
||||
const groupIds = items.map((i) => i.get("id") || -1);
|
||||
const names = items.map((i) => i.get("name"));
|
||||
|
||||
ajax("/admin/badges/badge_groupings", {
|
||||
data: { ids: groupIds, names },
|
||||
type: "POST",
|
||||
}).then(
|
||||
(data) => {
|
||||
items = this.model;
|
||||
items.clear();
|
||||
data.badge_groupings.forEach((g) => {
|
||||
items.pushObject(this.store.createRecord("badge-grouping", g));
|
||||
});
|
||||
this.setProperties({ model: null, workingCopy: null });
|
||||
this.send("closeModal");
|
||||
},
|
||||
() => this.dialog.alert(I18n.t("generic_error"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,15 +5,17 @@ import discourseComputed from "discourse-common/utils/decorators";
|
|||
import { longDate } from "discourse/lib/formatter";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
export default class AdminIncomingEmailController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@discourseComputed("model.date")
|
||||
date(d) {
|
||||
return longDate(d);
|
||||
},
|
||||
}
|
||||
|
||||
load(id) {
|
||||
return IncomingEmail.find(id).then((result) => this.set("model", result));
|
||||
},
|
||||
}
|
||||
|
||||
loadFromBounced(id) {
|
||||
return IncomingEmail.findByBounced(id)
|
||||
|
@ -22,5 +24,5 @@ export default Controller.extend(ModalFunctionality, {
|
|||
this.send("closeModal");
|
||||
popupAjaxError(error);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
import { alias, equal, match } from "@ember/object/computed";
|
||||
import { COMPONENTS, THEMES } from "admin/models/theme";
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import { alias, equal, match } from "@ember/object/computed";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { observes } from "@ember-decorators/object";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { POPULAR_THEMES } from "discourse-common/helpers/popular-themes";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { set } from "@ember/object";
|
||||
import { action, set } from "@ember/object";
|
||||
|
||||
const MIN_NAME_LENGTH = 4;
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
adminCustomizeThemes: controller(),
|
||||
themesController: controller("adminCustomizeThemes"),
|
||||
popular: equal("selection", "popular"),
|
||||
local: equal("selection", "local"),
|
||||
remote: equal("selection", "remote"),
|
||||
create: equal("selection", "create"),
|
||||
directRepoInstall: equal("selection", "directRepoInstall"),
|
||||
selection: "popular",
|
||||
loading: false,
|
||||
keyGenUrl: "/admin/themes/generate_key_pair",
|
||||
importUrl: "/admin/themes/import",
|
||||
recordType: "theme",
|
||||
checkPrivate: match("uploadUrl", /^ssh:\/\/.+@.+$|.+@.+:.+$/),
|
||||
localFile: null,
|
||||
uploadUrl: null,
|
||||
uploadName: null,
|
||||
advancedVisible: false,
|
||||
selectedType: alias("themesController.currentTab"),
|
||||
component: equal("selectedType", COMPONENTS),
|
||||
urlPlaceholder: "https://github.com/discourse/sample_theme",
|
||||
export default class AdminInstallThemeController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@controller adminCustomizeThemes;
|
||||
@controller("adminCustomizeThemes") themesController;
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
@equal("selection", "popular") popular;
|
||||
@equal("selection", "local") local;
|
||||
@equal("selection", "remote") remote;
|
||||
@equal("selection", "create") create;
|
||||
@equal("selection", "directRepoInstall") directRepoInstall;
|
||||
selection = "popular";
|
||||
loading = false;
|
||||
keyGenUrl = "/admin/themes/generate_key_pair";
|
||||
importUrl = "/admin/themes/import";
|
||||
recordType = "theme";
|
||||
@match("uploadUrl", /^ssh:\/\/.+@.+$|.+@.+:.+$/) checkPrivate;
|
||||
localFile = null;
|
||||
uploadUrl = null;
|
||||
uploadName = null;
|
||||
advancedVisible = false;
|
||||
@alias("themesController.currentTab") selectedType;
|
||||
@equal("selectedType", COMPONENTS) component;
|
||||
urlPlaceholder = "https://github.com/discourse/sample_theme";
|
||||
|
||||
this.createTypes = [
|
||||
{ name: I18n.t("admin.customize.theme.theme"), value: THEMES },
|
||||
{ name: I18n.t("admin.customize.theme.component"), value: COMPONENTS },
|
||||
];
|
||||
},
|
||||
createTypes = [
|
||||
{ name: I18n.t("admin.customize.theme.theme"), value: THEMES },
|
||||
{ name: I18n.t("admin.customize.theme.component"), value: COMPONENTS },
|
||||
];
|
||||
|
||||
@discourseComputed("themesController.installedThemes")
|
||||
themes(installedThemes) {
|
||||
|
@ -52,7 +52,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
}
|
||||
return t;
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed(
|
||||
"loading",
|
||||
|
@ -78,12 +78,12 @@ export default Controller.extend(ModalFunctionality, {
|
|||
(isLocal && !localFile) ||
|
||||
(isCreate && nameTooShort)
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("name")
|
||||
nameTooShort(name) {
|
||||
return !name || name.length < MIN_NAME_LENGTH;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("component")
|
||||
placeholder(component) {
|
||||
|
@ -92,7 +92,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
} else {
|
||||
return I18n.t("admin.customize.theme.theme_name");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@observes("checkPrivate")
|
||||
privateWasChecked() {
|
||||
|
@ -108,7 +108,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
this._keyLoading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("selection", "themeCannotBeInstalled")
|
||||
submitLabel(selection, themeCannotBeInstalled) {
|
||||
|
@ -119,12 +119,12 @@ export default Controller.extend(ModalFunctionality, {
|
|||
return `admin.customize.theme.${
|
||||
selection === "create" ? "create" : "install"
|
||||
}`;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("checkPrivate", "publicKey")
|
||||
showPublicKey(checkPrivate, publicKey) {
|
||||
return checkPrivate && publicKey;
|
||||
},
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.setProperties({
|
||||
|
@ -140,7 +140,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
repoName: null,
|
||||
repoUrl: null,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
themeHasSameUrl(theme, url) {
|
||||
const themeUrl = theme.remote_theme && theme.remote_theme.remote_url;
|
||||
|
@ -149,100 +149,101 @@ export default Controller.extend(ModalFunctionality, {
|
|||
url &&
|
||||
url.replace(/\.git$/, "") === themeUrl.replace(/\.git$/, "")
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
actions: {
|
||||
uploadLocaleFile() {
|
||||
this.set("localFile", $("#file-input")[0].files[0]);
|
||||
},
|
||||
@action
|
||||
uploadLocaleFile() {
|
||||
this.set("localFile", $("#file-input")[0].files[0]);
|
||||
}
|
||||
|
||||
toggleAdvanced() {
|
||||
this.toggleProperty("advancedVisible");
|
||||
},
|
||||
@action
|
||||
toggleAdvanced() {
|
||||
this.toggleProperty("advancedVisible");
|
||||
}
|
||||
|
||||
installThemeFromList(url) {
|
||||
this.set("uploadUrl", url);
|
||||
this.send("installTheme");
|
||||
},
|
||||
|
||||
installTheme() {
|
||||
if (this.create) {
|
||||
this.set("loading", true);
|
||||
const theme = this.store.createRecord(this.recordType);
|
||||
theme
|
||||
.save({ name: this.name, component: this.component })
|
||||
.then(() => {
|
||||
this.themesController.send("addTheme", theme);
|
||||
this.send("closeModal");
|
||||
})
|
||||
.catch(popupAjaxError)
|
||||
.finally(() => this.set("loading", false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let options = {
|
||||
type: "POST",
|
||||
};
|
||||
|
||||
if (this.local) {
|
||||
options.processData = false;
|
||||
options.contentType = false;
|
||||
options.data = new FormData();
|
||||
options.data.append("theme", this.localFile);
|
||||
}
|
||||
|
||||
if (this.remote || this.popular || this.directRepoInstall) {
|
||||
const duplicate = this.themesController.model.content.find((theme) =>
|
||||
this.themeHasSameUrl(theme, this.uploadUrl)
|
||||
);
|
||||
if (duplicate && !this.duplicateRemoteThemeWarning) {
|
||||
const warning = I18n.t(
|
||||
"admin.customize.theme.duplicate_remote_theme",
|
||||
{ name: duplicate.name }
|
||||
);
|
||||
this.set("duplicateRemoteThemeWarning", warning);
|
||||
return;
|
||||
}
|
||||
options.data = {
|
||||
remote: this.uploadUrl,
|
||||
branch: this.branch,
|
||||
public_key: this.publicKey,
|
||||
};
|
||||
}
|
||||
|
||||
// User knows that theme cannot be installed, but they want to continue
|
||||
// to force install it.
|
||||
if (this.themeCannotBeInstalled) {
|
||||
options.data["force"] = true;
|
||||
}
|
||||
|
||||
if (this.get("model.user_id")) {
|
||||
// Used by theme-creator
|
||||
options.data["user_id"] = this.get("model.user_id");
|
||||
}
|
||||
@action
|
||||
installThemeFromList(url) {
|
||||
this.set("uploadUrl", url);
|
||||
this.send("installTheme");
|
||||
}
|
||||
|
||||
@action
|
||||
installTheme() {
|
||||
if (this.create) {
|
||||
this.set("loading", true);
|
||||
ajax(this.importUrl, options)
|
||||
.then((result) => {
|
||||
const theme = this.store.createRecord(this.recordType, result.theme);
|
||||
this.adminCustomizeThemes.send("addTheme", theme);
|
||||
const theme = this.store.createRecord(this.recordType);
|
||||
theme
|
||||
.save({ name: this.name, component: this.component })
|
||||
.then(() => {
|
||||
this.themesController.send("addTheme", theme);
|
||||
this.send("closeModal");
|
||||
})
|
||||
.then(() => {
|
||||
this.set("publicKey", null);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (!this.publicKey || this.themeCannotBeInstalled) {
|
||||
return popupAjaxError(error);
|
||||
}
|
||||
|
||||
this.set(
|
||||
"themeCannotBeInstalled",
|
||||
I18n.t("admin.customize.theme.force_install")
|
||||
);
|
||||
})
|
||||
.catch(popupAjaxError)
|
||||
.finally(() => this.set("loading", false));
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let options = {
|
||||
type: "POST",
|
||||
};
|
||||
|
||||
if (this.local) {
|
||||
options.processData = false;
|
||||
options.contentType = false;
|
||||
options.data = new FormData();
|
||||
options.data.append("theme", this.localFile);
|
||||
}
|
||||
|
||||
if (this.remote || this.popular || this.directRepoInstall) {
|
||||
const duplicate = this.themesController.model.content.find((theme) =>
|
||||
this.themeHasSameUrl(theme, this.uploadUrl)
|
||||
);
|
||||
if (duplicate && !this.duplicateRemoteThemeWarning) {
|
||||
const warning = I18n.t("admin.customize.theme.duplicate_remote_theme", {
|
||||
name: duplicate.name,
|
||||
});
|
||||
this.set("duplicateRemoteThemeWarning", warning);
|
||||
return;
|
||||
}
|
||||
options.data = {
|
||||
remote: this.uploadUrl,
|
||||
branch: this.branch,
|
||||
public_key: this.publicKey,
|
||||
};
|
||||
}
|
||||
|
||||
// User knows that theme cannot be installed, but they want to continue
|
||||
// to force install it.
|
||||
if (this.themeCannotBeInstalled) {
|
||||
options.data["force"] = true;
|
||||
}
|
||||
|
||||
if (this.get("model.user_id")) {
|
||||
// Used by theme-creator
|
||||
options.data["user_id"] = this.get("model.user_id");
|
||||
}
|
||||
|
||||
this.set("loading", true);
|
||||
ajax(this.importUrl, options)
|
||||
.then((result) => {
|
||||
const theme = this.store.createRecord(this.recordType, result.theme);
|
||||
this.adminCustomizeThemes.send("addTheme", theme);
|
||||
this.send("closeModal");
|
||||
})
|
||||
.then(() => {
|
||||
this.set("publicKey", null);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (!this.publicKey || this.themeCannotBeInstalled) {
|
||||
return popupAjaxError(error);
|
||||
}
|
||||
|
||||
this.set(
|
||||
"themeCannotBeInstalled",
|
||||
I18n.t("admin.customize.theme.force_install")
|
||||
);
|
||||
})
|
||||
.finally(() => this.set("loading", false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import { alias } from "@ember/object/computed";
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { action } from "@ember/object";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
adminUserIndex: controller(),
|
||||
username: alias("model.username"),
|
||||
targetUsername: alias("model.targetUsername"),
|
||||
export default class AdminMergeUsersConfirmationController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@controller adminUserIndex;
|
||||
|
||||
@alias("model.username") username;
|
||||
@alias("model.targetUsername") targetUsername;
|
||||
|
||||
onShow() {
|
||||
this.set("value", null);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("username", "targetUsername")
|
||||
text(username, targetUsername) {
|
||||
|
@ -20,28 +23,28 @@ export default Controller.extend(ModalFunctionality, {
|
|||
username,
|
||||
targetUsername,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("username")
|
||||
mergeButtonText(username) {
|
||||
return I18n.t(`admin.user.merge.confirmation.transfer_and_delete`, {
|
||||
username,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("value", "text")
|
||||
mergeDisabled(value, text) {
|
||||
return !value || text !== value;
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
confirm() {
|
||||
this.adminUserIndex.send("merge", this.targetUsername);
|
||||
this.send("closeModal");
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
close() {
|
||||
this.send("closeModal");
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,18 @@ import I18n from "I18n";
|
|||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
message: I18n.t("admin.user.merging_user"),
|
||||
export default class AdminMergeUsersProgressController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
message = I18n.t("admin.user.merging_user");
|
||||
|
||||
onShow() {
|
||||
this.messageBus.subscribe("/merge_user", this.onMessage);
|
||||
},
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.messageBus.unsubscribe("/merge_user", this.onMessage);
|
||||
},
|
||||
}
|
||||
|
||||
@bind
|
||||
onMessage(data) {
|
||||
|
@ -30,5 +32,5 @@ export default Controller.extend(ModalFunctionality, {
|
|||
} else if (data.failed) {
|
||||
this.set("message", I18n.t("admin.user.merge_failed"));
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +1,46 @@
|
|||
import { alias } from "@ember/object/computed";
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { action, get } from "@ember/object";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
adminUserIndex: controller(),
|
||||
username: alias("model.username"),
|
||||
export default class AdminMergeUsersPromptController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@controller adminUserIndex;
|
||||
|
||||
@alias("model.username") username;
|
||||
|
||||
onShow() {
|
||||
this.set("targetUsername", null);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("username", "targetUsername")
|
||||
mergeDisabled(username, targetUsername) {
|
||||
return !targetUsername || username === targetUsername;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("username")
|
||||
mergeButtonText(username) {
|
||||
return I18n.t(`admin.user.merge.confirmation.transfer_and_delete`, {
|
||||
username,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
showConfirmation() {
|
||||
this.send("closeModal");
|
||||
this.adminUserIndex.send("showMergeConfirmation", this.targetUsername);
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
close() {
|
||||
this.send("closeModal");
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
updateUsername(selected) {
|
||||
this.set("targetUsername", get(selected, "firstObject"));
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
import { inject as service } from "@ember/service";
|
||||
import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import { next } from "@ember/runloop";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { extractError } from "discourse/lib/ajax-error";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
dialog: service(),
|
||||
export default class AdminPenalizeUserController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@service dialog;
|
||||
|
||||
loadingUser: false,
|
||||
errorMessage: null,
|
||||
penaltyType: null,
|
||||
penalizeUntil: null,
|
||||
reason: null,
|
||||
message: null,
|
||||
postId: null,
|
||||
postAction: null,
|
||||
postEdit: null,
|
||||
user: null,
|
||||
otherUserIds: null,
|
||||
loading: false,
|
||||
confirmClose: false,
|
||||
loadingUser = false;
|
||||
errorMessage = null;
|
||||
penaltyType = null;
|
||||
penalizeUntil = null;
|
||||
reason = null;
|
||||
message = null;
|
||||
postId = null;
|
||||
postAction = null;
|
||||
postEdit = null;
|
||||
user = null;
|
||||
otherUserIds = null;
|
||||
loading = false;
|
||||
confirmClose = false;
|
||||
|
||||
onShow() {
|
||||
this.setProperties({
|
||||
|
@ -44,11 +46,11 @@ export default Controller.extend(ModalFunctionality, {
|
|||
message: null,
|
||||
confirmClose: false,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
finishedSetup() {
|
||||
this.set("penalizeUntil", this.user?.next_penalty);
|
||||
},
|
||||
}
|
||||
|
||||
beforeClose() {
|
||||
if (this.confirmClose) {
|
||||
|
@ -73,7 +75,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("penaltyType")
|
||||
modalTitle(penaltyType) {
|
||||
|
@ -82,7 +84,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
} else if (penaltyType === "silence") {
|
||||
return "admin.user.silence_modal_title";
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("penaltyType")
|
||||
buttonLabel(penaltyType) {
|
||||
|
@ -91,7 +93,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
} else if (penaltyType === "silence") {
|
||||
return "admin.user.silence";
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed(
|
||||
"user.penalty_counts.suspended",
|
||||
|
@ -102,7 +104,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
SUSPENDED: suspendedCount,
|
||||
SILENCED: silencedCount,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("penaltyType", "user.canSuspend", "user.canSilence")
|
||||
canPenalize(penaltyType, canSuspend, canSilence) {
|
||||
|
@ -113,12 +115,12 @@ export default Controller.extend(ModalFunctionality, {
|
|||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("penalizing", "penalizeUntil", "reason")
|
||||
submitDisabled(penalizing, penalizeUntil, reason) {
|
||||
return penalizing || isEmpty(penalizeUntil) || !reason || reason.length < 1;
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
async penalizeUser() {
|
||||
|
@ -164,5 +166,5 @@ export default Controller.extend(ModalFunctionality, {
|
|||
} finally {
|
||||
this.set("penalizing", false);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
import Controller from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
dialog: service(),
|
||||
loading: true,
|
||||
reseeding: false,
|
||||
categories: null,
|
||||
topics: null,
|
||||
export default class AdminReseedController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@service dialog;
|
||||
|
||||
loading = true;
|
||||
reseeding = false;
|
||||
categories = null;
|
||||
topics = null;
|
||||
|
||||
onShow() {
|
||||
ajax("/admin/customize/reseed")
|
||||
|
@ -20,27 +24,26 @@ export default Controller.extend(ModalFunctionality, {
|
|||
});
|
||||
})
|
||||
.finally(() => this.set("loading", false));
|
||||
},
|
||||
}
|
||||
|
||||
_extractSelectedIds(items) {
|
||||
return items.filter((item) => item.selected).map((item) => item.id);
|
||||
},
|
||||
}
|
||||
|
||||
actions: {
|
||||
reseed() {
|
||||
this.set("reseeding", true);
|
||||
ajax("/admin/customize/reseed", {
|
||||
data: {
|
||||
category_ids: this._extractSelectedIds(this.categories),
|
||||
topic_ids: this._extractSelectedIds(this.topics),
|
||||
},
|
||||
type: "POST",
|
||||
})
|
||||
.catch(() => this.dialog.alert(I18n.t("generic_error")))
|
||||
.finally(() => {
|
||||
this.set("reseeding", false);
|
||||
this.send("closeModal");
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@action
|
||||
reseed() {
|
||||
this.set("reseeding", true);
|
||||
ajax("/admin/customize/reseed", {
|
||||
data: {
|
||||
category_ids: this._extractSelectedIds(this.categories),
|
||||
topic_ids: this._extractSelectedIds(this.topics),
|
||||
},
|
||||
type: "POST",
|
||||
})
|
||||
.catch(() => this.dialog.alert(I18n.t("generic_error")))
|
||||
.finally(() => {
|
||||
this.set("reseeding", false);
|
||||
this.send("closeModal");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Controller from "@ember/controller";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
|
||||
export default Controller.extend(ModalFunctionality);
|
||||
export default class AdminStaffActionLogDetailsController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {}
|
||||
|
|
|
@ -1,35 +1,39 @@
|
|||
import { action } from "@ember/object";
|
||||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
adminBackupsLogs: controller(),
|
||||
export default class AdminStartBackupController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@controller adminBackupsLogs;
|
||||
|
||||
@discourseComputed
|
||||
warningMessage() {
|
||||
// this is never shown here, but we may want to show different
|
||||
// messages in plugins
|
||||
return "";
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed
|
||||
yesLabel() {
|
||||
return "yes_value";
|
||||
},
|
||||
}
|
||||
|
||||
actions: {
|
||||
startBackupWithUploads() {
|
||||
this.send("closeModal");
|
||||
this.send("startBackup", true);
|
||||
},
|
||||
@action
|
||||
startBackupWithUploads() {
|
||||
this.send("closeModal");
|
||||
this.send("startBackup", true);
|
||||
}
|
||||
|
||||
startBackupWithoutUploads() {
|
||||
this.send("closeModal");
|
||||
this.send("startBackup", false);
|
||||
},
|
||||
@action
|
||||
startBackupWithoutUploads() {
|
||||
this.send("closeModal");
|
||||
this.send("startBackup", false);
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.send("closeModal");
|
||||
},
|
||||
},
|
||||
});
|
||||
@action
|
||||
cancel() {
|
||||
this.send("closeModal");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ import Controller from "@ember/controller";
|
|||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
export default class AdminThemeChangeController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
loadDiff() {
|
||||
this.set("loading", true);
|
||||
ajax(
|
||||
|
@ -11,5 +13,5 @@ export default Controller.extend(ModalFunctionality, {
|
|||
this.set("loading", false);
|
||||
this.set("diff", diff.side_by_side);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
import { observes, on } from "discourse-common/utils/decorators";
|
||||
import { observes, on } from "@ember-decorators/object";
|
||||
import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
export default class AdminUploadedImageListController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@on("init")
|
||||
@observes("model.value")
|
||||
_setup() {
|
||||
const value = this.get("model.value");
|
||||
this.set("images", value && value.length ? value.split("|") : []);
|
||||
},
|
||||
}
|
||||
|
||||
@action
|
||||
remove(url, event) {
|
||||
event?.preventDefault();
|
||||
this.images.removeObject(url);
|
||||
},
|
||||
}
|
||||
|
||||
actions: {
|
||||
uploadDone({ url }) {
|
||||
this.images.addObject(url);
|
||||
},
|
||||
@action
|
||||
uploadDone({ url }) {
|
||||
this.images.addObject(url);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.save(this.images.join("|"));
|
||||
this.send("closeModal");
|
||||
},
|
||||
},
|
||||
});
|
||||
@action
|
||||
close() {
|
||||
this.save(this.images.join("|"));
|
||||
this.send("closeModal");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import { equal } from "@ember/object/computed";
|
||||
import Controller from "@ember/controller";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { equal } from "@ember/object/computed";
|
||||
import {
|
||||
createWatchedWordRegExp,
|
||||
toWatchedWord,
|
||||
} from "discourse-common/utils/watched-words";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
isReplace: equal("model.nameKey", "replace"),
|
||||
isTag: equal("model.nameKey", "tag"),
|
||||
isLink: equal("model.nameKey", "link"),
|
||||
export default class AdminWatchedWordTestController extends Controller.extend(
|
||||
ModalFunctionality
|
||||
) {
|
||||
@equal("model.nameKey", "replace") isReplace;
|
||||
|
||||
@equal("model.nameKey", "tag") isTag;
|
||||
@equal("model.nameKey", "link") isLink;
|
||||
|
||||
@discourseComputed(
|
||||
"value",
|
||||
|
@ -71,5 +74,5 @@ export default Controller.extend(ModalFunctionality, {
|
|||
|
||||
return matches;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,4 +2,7 @@ import Controller from "@ember/controller";
|
|||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import ModalUpdateExistingUsers from "discourse/mixins/modal-update-existing-users";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, ModalUpdateExistingUsers);
|
||||
export default class SiteSettingDefaultCategoriesController extends Controller.extend(
|
||||
ModalFunctionality,
|
||||
ModalUpdateExistingUsers
|
||||
) {}
|
||||
|
|
Loading…
Reference in New Issue