mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 05:03:39 +08:00
DEV: Convert helpers into plain functions (#22385)
Since 0fa92529ed
, helpers can now be implemented as plain JS functions. This makes them much easier to write/read, and also makes them usable in `<template>` gjs files.
This commit is contained in:
parent
238d71bcad
commit
9bbd5efbec
|
@ -5,7 +5,7 @@ import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import { observes } from "@ember-decorators/object";
|
import { observes } from "@ember-decorators/object";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||||
import { POPULAR_THEMES } from "discourse-common/helpers/popular-themes";
|
import { POPULAR_THEMES } from "discourse-common/lib/popular-themes";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import { action, set } from "@ember/object";
|
import { action, set } from "@ember/object";
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
export default htmlHelper((key, params) => I18n.t(key, params.hash));
|
export default function boundI18n(key, options) {
|
||||||
|
return htmlSafe(I18n.t(key, options));
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
const validDirections = ["top", "right", "bottom", "left"];
|
const validDirections = ["top", "right", "bottom", "left"];
|
||||||
|
|
||||||
export default htmlHelper((color, direction) => {
|
export default function borderColor(color, direction) {
|
||||||
const borderColor = `#${color}`;
|
|
||||||
|
|
||||||
const borderProperty =
|
const borderProperty =
|
||||||
direction && validDirections.includes(direction)
|
direction && validDirections.includes(direction)
|
||||||
? `border-${direction}-color`
|
? `border-${direction}-color`
|
||||||
: "border-color";
|
: "border-color";
|
||||||
|
|
||||||
return `${borderProperty}: ${borderColor} `;
|
return htmlSafe(`${borderProperty}: #${color} `);
|
||||||
});
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
import { avatarImg } from "discourse-common/lib/avatar-utils";
|
import { avatarImg } from "discourse-common/lib/avatar-utils";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
|
||||||
export default htmlHelper((avatarTemplate, size) => {
|
export default function boundAvatarTemplate(avatarTemplate, size) {
|
||||||
if (isEmpty(avatarTemplate)) {
|
if (isEmpty(avatarTemplate)) {
|
||||||
return "<div class='avatar-placeholder'></div>";
|
return htmlSafe("<div class='avatar-placeholder'></div>");
|
||||||
} else {
|
} else {
|
||||||
return avatarImg({ size, avatarTemplate });
|
return htmlSafe(avatarImg({ size, avatarTemplate }));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
import { addExtraUserClasses } from "discourse/helpers/user-avatar";
|
import { addExtraUserClasses } from "discourse/helpers/user-avatar";
|
||||||
import { avatarImg } from "discourse-common/lib/avatar-utils";
|
import { avatarImg } from "discourse-common/lib/avatar-utils";
|
||||||
import { get } from "@ember/object";
|
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
|
||||||
export default htmlHelper((user, size) => {
|
export default function boundAvatar(user, size) {
|
||||||
if (isEmpty(user)) {
|
if (isEmpty(user)) {
|
||||||
return "<div class='avatar-placeholder'></div>";
|
return htmlSafe("<div class='avatar-placeholder'></div>");
|
||||||
}
|
}
|
||||||
|
|
||||||
const avatarTemplate = get(user, "avatar_template");
|
return htmlSafe(
|
||||||
return avatarImg(addExtraUserClasses(user, { size, avatarTemplate }));
|
avatarImg(
|
||||||
});
|
addExtraUserClasses(user, { size, avatarTemplate: user.avatar_template })
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1 @@
|
||||||
import { categoryLinkHTML } from "discourse/helpers/category-link";
|
export { categoryLinkHTML as default } from "discourse/helpers/category-link";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
|
|
||||||
export default htmlHelper(categoryLinkHTML);
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
|
import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
|
|
||||||
export default htmlHelper((dt) =>
|
export default function boundDate(dt) {
|
||||||
autoUpdatingRelativeAge(new Date(dt), { format: "medium", title: true })
|
return htmlSafe(
|
||||||
);
|
autoUpdatingRelativeAge(new Date(dt), {
|
||||||
|
format: "medium",
|
||||||
|
title: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
import deprecated from "discourse-common/lib/deprecated";
|
||||||
|
|
||||||
export default htmlHelper((str) => str[0].toUpperCase() + str.slice(1));
|
export default function capitalizeString(str) {
|
||||||
|
deprecated("capitalize-string helper is deprecated", {
|
||||||
|
id: "discourse.capitalize-string",
|
||||||
|
since: "3.1.0.beta6",
|
||||||
|
});
|
||||||
|
return str[0].toUpperCase() + str.slice(1);
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
export default htmlHelper((color) => `--category-color: #${color};`);
|
export default function categoryColorVariable(color) {
|
||||||
|
return htmlSafe(`--category-color: #${color};`);
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { helper } from "@ember/component/helper";
|
export default function concatClass(...args) {
|
||||||
|
|
||||||
function concatClass(args) {
|
|
||||||
const classes = args.compact().join(" ");
|
const classes = args.compact().join(" ");
|
||||||
return classes.length ? classes : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default helper(concatClass);
|
if (classes.length) {
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
import { htmlSafe } from "@ember/template";
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
|
||||||
export default htmlHelper((str) => (isEmpty(str) ? "—" : str));
|
export default function dashIfEmpty(str) {
|
||||||
|
return isEmpty(str) ? htmlSafe("—") : str;
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
import Helper from "@ember/component/helper";
|
|
||||||
import { dasherize as emberDasherize } from "@ember/string";
|
import { dasherize as emberDasherize } from "@ember/string";
|
||||||
|
|
||||||
function dasherize([value]) {
|
export default function dasherize(value = "") {
|
||||||
return emberDasherize((value || "").replace(".", "-"));
|
return emberDasherize(value.replace(".", "-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Helper.helper(dasherize);
|
|
||||||
|
|
|
@ -1,20 +1,17 @@
|
||||||
import Helper from "@ember/component/helper";
|
|
||||||
import { get } from "@ember/object";
|
import { get } from "@ember/object";
|
||||||
|
|
||||||
export function formatCurrency([reviewable, fieldId]) {
|
export default function editableValue(reviewable, fieldId) {
|
||||||
// The field `category_id` corresponds to `category`
|
// The field `category_id` corresponds to `category`
|
||||||
if (fieldId === "category_id") {
|
if (fieldId === "category_id") {
|
||||||
fieldId = "category.id";
|
fieldId = "category.id";
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = get(reviewable, fieldId);
|
const value = get(reviewable, fieldId);
|
||||||
|
|
||||||
// If it's an array, say tags, make a copy so we aren't mutating the original
|
// If it's an array, say tags, make a copy so we aren't mutating the original
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
value = value.slice(0);
|
return value.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Helper.helper(formatCurrency);
|
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import { convertIconClass, iconHTML } from "discourse-common/lib/icon-library";
|
import { convertIconClass, iconHTML } from "discourse-common/lib/icon-library";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
export default htmlHelper(function ({ icon, image }) {
|
export default function iconOrImage({ icon, image }) {
|
||||||
if (!isEmpty(image)) {
|
if (!isEmpty(image)) {
|
||||||
return `<img src='${image}'>`;
|
return htmlSafe(`<img src='${image}'>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEmpty(icon)) {
|
if (isEmpty(icon)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
icon = convertIconClass(icon);
|
return htmlSafe(iconHTML(convertIconClass(icon)));
|
||||||
return iconHTML(icon);
|
}
|
||||||
});
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
import { registerHelper } from "discourse-common/lib/helpers";
|
import deprecated from "discourse-common/lib/deprecated";
|
||||||
import { relativeAge } from "discourse/lib/formatter";
|
import { relativeAge } from "discourse/lib/formatter";
|
||||||
|
|
||||||
registerHelper("inline-date", function ([dt]) {
|
export default function inlineDate(dt) {
|
||||||
// TODO: Remove this in 1.13 or greater
|
deprecated("inline-date helper is deprecated", {
|
||||||
|
id: "discourse.inline-date",
|
||||||
|
since: "3.1.0.beta6",
|
||||||
|
});
|
||||||
|
|
||||||
if (dt.value) {
|
if (dt.value) {
|
||||||
dt = dt.value();
|
dt = dt.value();
|
||||||
}
|
}
|
||||||
return relativeAge(new Date(dt));
|
return relativeAge(new Date(dt));
|
||||||
});
|
}
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
function renderSpinner(cssClass) {
|
export function renderSpinner(cssClass) {
|
||||||
let html = "<div class='spinner";
|
let html = "<div class='spinner";
|
||||||
if (cssClass) {
|
if (cssClass) {
|
||||||
html += " " + cssClass;
|
html += " " + cssClass;
|
||||||
}
|
}
|
||||||
return html + "'></div>";
|
return html + "'></div>";
|
||||||
}
|
}
|
||||||
let spinnerHTML = renderSpinner();
|
|
||||||
|
|
||||||
export default htmlHelper((params) => {
|
export const spinnerHTML = renderSpinner();
|
||||||
const hash = params.hash;
|
|
||||||
return renderSpinner(hash && hash.size ? hash.size : undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
export { spinnerHTML, renderSpinner };
|
export default function loadingSpinner({ size } = {}) {
|
||||||
|
return htmlSafe(renderSpinner(size));
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
const TITLE_SUBS = {
|
const TITLE_SUBS = {
|
||||||
all: "all_time",
|
all: "all_time",
|
||||||
|
@ -9,13 +9,17 @@ const TITLE_SUBS = {
|
||||||
daily: "today",
|
daily: "today",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default htmlHelper((period, options) => {
|
export default function periodTitle(period, { showDateRange, fullDay } = {}) {
|
||||||
const title = I18n.t("filters.top." + (TITLE_SUBS[period] || "this_week"));
|
const title = I18n.t("filters.top." + (TITLE_SUBS[period] || "this_week"));
|
||||||
if (options.hash.showDateRange) {
|
|
||||||
|
if (!showDateRange) {
|
||||||
|
return htmlSafe(title);
|
||||||
|
}
|
||||||
|
|
||||||
let dateString = "";
|
let dateString = "";
|
||||||
let finish;
|
let finish;
|
||||||
|
|
||||||
if (options.hash.fullDay) {
|
if (fullDay) {
|
||||||
finish = moment().utc().subtract(1, "days");
|
finish = moment().utc().subtract(1, "days");
|
||||||
} else {
|
} else {
|
||||||
finish = moment();
|
finish = moment();
|
||||||
|
@ -42,7 +46,7 @@ export default htmlHelper((period, options) => {
|
||||||
break;
|
break;
|
||||||
case "weekly":
|
case "weekly":
|
||||||
let start;
|
let start;
|
||||||
if (options.hash.fullDay) {
|
if (fullDay) {
|
||||||
start = finish.clone().subtract(1, "week");
|
start = finish.clone().subtract(1, "week");
|
||||||
} else {
|
} else {
|
||||||
start = finish.clone().subtract(6, "days");
|
start = finish.clone().subtract(6, "days");
|
||||||
|
@ -63,14 +67,11 @@ export default htmlHelper((period, options) => {
|
||||||
finish.format(I18n.t("dates.long_no_year_no_time"));
|
finish.format(I18n.t("dates.long_no_year_no_time"));
|
||||||
break;
|
break;
|
||||||
case "daily":
|
case "daily":
|
||||||
dateString = finish
|
dateString = finish.clone().format(I18n.t("dates.full_no_year_no_time"));
|
||||||
.clone()
|
|
||||||
.format(I18n.t("dates.full_no_year_no_time"));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `<span class="date-section">${title}</span><span class='top-date-string'>${dateString}</span>`;
|
return htmlSafe(
|
||||||
} else {
|
`<span class="date-section">${title}</span><span class='top-date-string'>${dateString}</span>`
|
||||||
return title;
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import { EDITED } from "discourse/models/reviewable-history";
|
import { EDITED } from "discourse/models/reviewable-history";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
import { htmlStatus } from "discourse/helpers/reviewable-status";
|
import { htmlStatus } from "discourse/helpers/reviewable-status";
|
||||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
export default htmlHelper(function (rh) {
|
export default function reviewableHistoryDescription(rh) {
|
||||||
switch (rh.reviewable_history_type) {
|
switch (rh.reviewable_history_type) {
|
||||||
case EDITED:
|
case EDITED:
|
||||||
return iconHTML("pencil-alt") + " " + I18n.t("review.history.edited");
|
return htmlSafe(
|
||||||
|
iconHTML("pencil-alt") + " " + I18n.t("review.history.edited")
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return htmlStatus(rh.status);
|
return htmlSafe(htmlStatus(rh.status));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import {
|
||||||
REJECTED,
|
REJECTED,
|
||||||
} from "discourse/models/reviewable";
|
} from "discourse/models/reviewable";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
function dataFor(status, type) {
|
function dataFor(status, type) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -81,6 +81,6 @@ export function htmlStatus(status, type) {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default htmlHelper((status, type) => {
|
export default function (status, type) {
|
||||||
return htmlStatus(status, type);
|
return htmlSafe(htmlStatus(status, type));
|
||||||
});
|
}
|
||||||
|
|
|
@ -1,27 +1,28 @@
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { escapeExpression } from "discourse/lib/utilities";
|
import { escapeExpression } from "discourse/lib/utilities";
|
||||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
|
||||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
|
||||||
export default htmlHelper((user, args) => {
|
export default function userStatus(user, { currentUser } = {}) {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = escapeExpression(user.get("name"));
|
const name = escapeExpression(user.name);
|
||||||
let currentUser;
|
|
||||||
if (args && args.hash) {
|
if (user.admin && currentUser?.staff) {
|
||||||
currentUser = args.hash.currentUser;
|
return htmlSafe(
|
||||||
|
iconHTML("shield-alt", {
|
||||||
|
label: I18n.t("user.admin", { user: name }),
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentUser && user.get("admin") && currentUser.get("staff")) {
|
if (user.moderator) {
|
||||||
return iconHTML("shield-alt", {
|
return htmlSafe(
|
||||||
label: I18n.t("user.admin", { user: name }),
|
iconHTML("shield-alt", {
|
||||||
});
|
|
||||||
}
|
|
||||||
if (user.get("moderator")) {
|
|
||||||
return iconHTML("shield-alt", {
|
|
||||||
label: I18n.t("user.moderator", { user: name }),
|
label: I18n.t("user.moderator", { user: name }),
|
||||||
});
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user