mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
REFACTOR: setting component mixin (#14437)
* REFACTOR: setting component mixing - drops jquery usage - extract spit function - uses @action - removes get usage where possible - uses helpers - minor changes Co-authored-by: Jarek Radosz <jradosz@gmail.com>
This commit is contained in:
@@ -1,14 +1,18 @@
|
|||||||
|
import { isNone } from "@ember/utils";
|
||||||
|
import { fmt, propertyNotEqual } from "discourse/lib/computed";
|
||||||
import { alias, oneWay } from "@ember/object/computed";
|
import { alias, oneWay } from "@ember/object/computed";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import Mixin from "@ember/object/mixin";
|
import Mixin from "@ember/object/mixin";
|
||||||
import { Promise } from "rsvp";
|
import { Promise } from "rsvp";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { categoryLinkHTML } from "discourse/helpers/category-link";
|
import { categoryLinkHTML } from "discourse/helpers/category-link";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed, { bind } from "discourse-common/utils/decorators";
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
import { on } from "@ember/object/evented";
|
import { on } from "@ember/object/evented";
|
||||||
import showModal from "discourse/lib/show-modal";
|
import showModal from "discourse/lib/show-modal";
|
||||||
import { warn } from "@ember/debug";
|
import { warn } from "@ember/debug";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { splitString } from "discourse/lib/utilities";
|
||||||
|
|
||||||
const CUSTOM_TYPES = [
|
const CUSTOM_TYPES = [
|
||||||
"bool",
|
"bool",
|
||||||
@@ -32,26 +36,20 @@ const CUSTOM_TYPES = [
|
|||||||
|
|
||||||
const AUTO_REFRESH_ON_SAVE = ["logo", "logo_small", "large_icon"];
|
const AUTO_REFRESH_ON_SAVE = ["logo", "logo_small", "large_icon"];
|
||||||
|
|
||||||
function splitPipes(str) {
|
|
||||||
if (typeof str === "string") {
|
|
||||||
return str.split("|").filter(Boolean);
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Mixin.create({
|
export default Mixin.create({
|
||||||
classNameBindings: [":row", ":setting", "overridden", "typeClass"],
|
classNameBindings: [":row", ":setting", "overridden", "typeClass"],
|
||||||
content: alias("setting"),
|
content: alias("setting"),
|
||||||
validationMessage: null,
|
validationMessage: null,
|
||||||
isSecret: oneWay("setting.secret"),
|
isSecret: oneWay("setting.secret"),
|
||||||
|
setting: null,
|
||||||
|
|
||||||
@discourseComputed("buffered.value", "setting.value")
|
@discourseComputed("buffered.value", "setting.value")
|
||||||
dirty(bufferVal, settingVal) {
|
dirty(bufferVal, settingVal) {
|
||||||
if (bufferVal === null || bufferVal === undefined) {
|
if (isNone(bufferVal)) {
|
||||||
bufferVal = "";
|
bufferVal = "";
|
||||||
}
|
}
|
||||||
if (settingVal === null || settingVal === undefined) {
|
|
||||||
|
if (isNone(settingVal)) {
|
||||||
settingVal = "";
|
settingVal = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,21 +59,17 @@ export default Mixin.create({
|
|||||||
@discourseComputed("setting", "buffered.value")
|
@discourseComputed("setting", "buffered.value")
|
||||||
preview(setting, value) {
|
preview(setting, value) {
|
||||||
// A bit hacky, but allows us to use helpers
|
// A bit hacky, but allows us to use helpers
|
||||||
if (setting.get("setting") === "category_style") {
|
if (setting.setting === "category_style") {
|
||||||
let category = this.site.get("categories.firstObject");
|
const category = this.site.get("categories.firstObject");
|
||||||
if (category) {
|
if (category) {
|
||||||
return categoryLinkHTML(category, {
|
return categoryLinkHTML(category, { categoryStyle: value });
|
||||||
categoryStyle: value,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let preview = setting.get("preview");
|
|
||||||
|
const preview = setting.preview;
|
||||||
if (preview) {
|
if (preview) {
|
||||||
return htmlSafe(
|
const escapedValue = preview.replace(/\{\{value\}\}/g, value);
|
||||||
"<div class='preview'>" +
|
return htmlSafe(`<div class='preview'>${escapedValue}</div>`);
|
||||||
preview.replace(/\{\{value\}\}/g, value) +
|
|
||||||
"</div>"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -103,61 +97,34 @@ export default Mixin.create({
|
|||||||
return setting.type;
|
return setting.type;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed("typeClass")
|
componentName: fmt("typeClass", "site-settings/%@"),
|
||||||
componentName(typeClass) {
|
|
||||||
return "site-settings/" + typeClass;
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("setting.anyValue")
|
@discourseComputed("setting.anyValue")
|
||||||
allowAny(anyValue) {
|
allowAny(anyValue) {
|
||||||
return anyValue !== false;
|
return anyValue !== false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed("setting.default", "buffered.value")
|
overridden: propertyNotEqual("setting.default", "buffered.value"),
|
||||||
overridden(settingDefault, bufferedValue) {
|
|
||||||
return settingDefault !== bufferedValue;
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("buffered.value")
|
@discourseComputed("buffered.value")
|
||||||
bufferedValues: splitPipes,
|
bufferedValues(value) {
|
||||||
|
return splitString(value, "|");
|
||||||
|
},
|
||||||
|
|
||||||
@discourseComputed("setting.defaultValues")
|
@discourseComputed("setting.defaultValues")
|
||||||
defaultValues: splitPipes,
|
defaultValues(value) {
|
||||||
|
return splitString(value, "|");
|
||||||
|
},
|
||||||
|
|
||||||
@discourseComputed("defaultValues", "bufferedValues")
|
@discourseComputed("defaultValues", "bufferedValues")
|
||||||
defaultIsAvailable(defaultValues, bufferedValues) {
|
defaultIsAvailable(defaultValues, bufferedValues) {
|
||||||
return (
|
return (
|
||||||
defaultValues &&
|
|
||||||
defaultValues.length > 0 &&
|
defaultValues.length > 0 &&
|
||||||
!defaultValues.every((value) => bufferedValues.includes(value))
|
!defaultValues.every((value) => bufferedValues.includes(value))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
_watchEnterKey: on("didInsertElement", function () {
|
@action
|
||||||
$(this.element).on(
|
|
||||||
"keydown.setting-enter",
|
|
||||||
".input-setting-string",
|
|
||||||
(e) => {
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
// enter key
|
|
||||||
this.send("save");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
|
|
||||||
_removeBindings: on("willDestroyElement", function () {
|
|
||||||
$(this.element).off("keydown.setting-enter");
|
|
||||||
}),
|
|
||||||
|
|
||||||
_save() {
|
|
||||||
warn("You should define a `_save` method", {
|
|
||||||
id: "discourse.setting-component.missing-save",
|
|
||||||
});
|
|
||||||
return Promise.resolve();
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
update() {
|
update() {
|
||||||
const defaultUserPreferences = [
|
const defaultUserPreferences = [
|
||||||
"default_email_digest_frequency",
|
"default_email_digest_frequency",
|
||||||
@@ -204,26 +171,24 @@ export default Mixin.create({
|
|||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
const controller = showModal("site-setting-default-categories", {
|
const controller = showModal("site-setting-default-categories", {
|
||||||
model: {
|
model: { count, key: key.replaceAll("_", " ") },
|
||||||
count: result.user_count,
|
|
||||||
key: key.replace(/_/g, " "),
|
|
||||||
},
|
|
||||||
admin: true,
|
admin: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
controller.set("onClose", () => {
|
controller.set("onClose", () => {
|
||||||
this.updateExistingUsers = controller.updateExistingUsers;
|
this.updateExistingUsers = controller.updateExistingUsers;
|
||||||
this.send("save");
|
this.save();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.send("save");
|
this.save();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.send("save");
|
this.save();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
save() {
|
save() {
|
||||||
this._save()
|
this._save()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -234,7 +199,7 @@ export default Mixin.create({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
|
if (e.jqXHR?.responseJSON?.errors) {
|
||||||
this.set("validationMessage", e.jqXHR.responseJSON.errors[0]);
|
this.set("validationMessage", e.jqXHR.responseJSON.errors[0]);
|
||||||
} else {
|
} else {
|
||||||
this.set("validationMessage", I18n.t("generic_error"));
|
this.set("validationMessage", I18n.t("generic_error"));
|
||||||
@@ -242,18 +207,22 @@ export default Mixin.create({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
cancel() {
|
cancel() {
|
||||||
this.rollbackBuffer();
|
this.rollbackBuffer();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
resetDefault() {
|
resetDefault() {
|
||||||
this.set("buffered.value", this.get("setting.default"));
|
this.set("buffered.value", this.get("setting.default"));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
toggleSecret() {
|
toggleSecret() {
|
||||||
this.toggleProperty("isSecret");
|
this.toggleProperty("isSecret");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
setDefaultValues() {
|
setDefaultValues() {
|
||||||
this.set(
|
this.set(
|
||||||
"buffered.value",
|
"buffered.value",
|
||||||
@@ -261,5 +230,29 @@ export default Mixin.create({
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@bind
|
||||||
|
_handleKeydown(event) {
|
||||||
|
if (
|
||||||
|
event.key === "Enter" &&
|
||||||
|
event.target.classList.contains("input-setting-string")
|
||||||
|
) {
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_watchEnterKey: on("didInsertElement", function () {
|
||||||
|
this.element.addEventListener("keydown", this._handleKeydown);
|
||||||
|
}),
|
||||||
|
|
||||||
|
_removeBindings: on("willDestroyElement", function () {
|
||||||
|
this.element.removeEventListener("keydown", this._handleKeydown);
|
||||||
|
}),
|
||||||
|
|
||||||
|
_save() {
|
||||||
|
warn("You should define a `_save` method", {
|
||||||
|
id: "discourse.setting-component.missing-save",
|
||||||
|
});
|
||||||
|
return Promise.resolve();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ import toMarkdown from "discourse/lib/to-markdown";
|
|||||||
|
|
||||||
let _defaultHomepage;
|
let _defaultHomepage;
|
||||||
|
|
||||||
|
export function splitString(str, separator = ",") {
|
||||||
|
if (typeof str === "string") {
|
||||||
|
return str.split(separator).filter(Boolean);
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function translateSize(size) {
|
export function translateSize(size) {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case "tiny":
|
case "tiny":
|
||||||
|
|||||||
Reference in New Issue
Block a user