Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-09 20:02:54 +01:00
fixed linting issues for javascripts/wizard folder (#94)
* ran eslint and fixes linting issues for javascripts/wizard folder * ran prettier
Dieser Commit ist enthalten in:
Ursprung
54c00f1784
Commit
0205d8ccb5
25 geänderte Dateien mit 108 neuen und 71 gelöschten Zeilen
|
@ -1,4 +1,5 @@
|
|||
window.Discourse = {}
|
||||
/* eslint no-undef: 0*/
|
||||
window.Discourse = {};
|
||||
window.Wizard = {};
|
||||
Wizard.SiteSettings = {};
|
||||
Discourse.__widget_helpers = {};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(function () {
|
||||
document.cookie = 'destination_url=' + window.location.href + ';path=/';
|
||||
window.location.href = '/login'
|
||||
})()
|
||||
window.location.href = '/login';
|
||||
})();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(function() {
|
||||
var wizard = require('discourse/plugins/discourse-custom-wizard/wizard/custom-wizard').default.create();
|
||||
let wizard = require('discourse/plugins/discourse-custom-wizard/wizard/custom-wizard').default.create();
|
||||
wizard.start();
|
||||
})();
|
||||
|
|
|
@ -5,6 +5,8 @@ import {
|
|||
import { renderAvatar } from "discourse/helpers/user-avatar";
|
||||
import userSearch from "../lib/user-search";
|
||||
import WizardI18n from "../lib/wizard-i18n";
|
||||
import Handlebars from "handlebars";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
|
||||
const template = function (params) {
|
||||
const options = params.options;
|
||||
|
@ -43,13 +45,14 @@ export default Ember.TextField.extend({
|
|||
|
||||
@observes("usernames")
|
||||
_update() {
|
||||
if (this.get("canReceiveUpdates") === "true")
|
||||
if (this.get("canReceiveUpdates") === "true") {
|
||||
this.didInsertElement({ updateData: true });
|
||||
}
|
||||
},
|
||||
|
||||
didInsertElement(opts) {
|
||||
this._super();
|
||||
var self = this,
|
||||
let self = this,
|
||||
selected = [],
|
||||
groups = [],
|
||||
currentUser = this.currentUser,
|
||||
|
@ -82,7 +85,7 @@ export default Ember.TextField.extend({
|
|||
dataSource(term) {
|
||||
const termRegex = /[^a-zA-Z0-9_\-\.@\+]/;
|
||||
|
||||
var results = userSearch({
|
||||
let results = userSearch({
|
||||
term: term.replace(termRegex, ""),
|
||||
topicId: self.get("topicId"),
|
||||
exclude: excludedUsernames(),
|
||||
|
@ -102,7 +105,7 @@ export default Ember.TextField.extend({
|
|||
}
|
||||
return v.username || v.name;
|
||||
} else {
|
||||
var excludes = excludedUsernames();
|
||||
let excludes = excludedUsernames();
|
||||
return v.usernames.filter(function (item) {
|
||||
return excludes.indexOf(item) === -1;
|
||||
});
|
||||
|
@ -110,7 +113,7 @@ export default Ember.TextField.extend({
|
|||
},
|
||||
|
||||
onChangeItems(items) {
|
||||
var hasGroups = false;
|
||||
let hasGroups = false;
|
||||
items = items.map(function (i) {
|
||||
if (groups.indexOf(i) > -1) {
|
||||
hasGroups = true;
|
||||
|
@ -121,7 +124,9 @@ export default Ember.TextField.extend({
|
|||
self.set("hasGroups", hasGroups);
|
||||
|
||||
selected = items;
|
||||
if (self.get("onChangeCallback")) self.sendAction("onChangeCallback");
|
||||
if (self.get("onChangeCallback")) {
|
||||
self.sendAction("onChangeCallback");
|
||||
}
|
||||
},
|
||||
|
||||
reverseTransform(i) {
|
||||
|
@ -139,7 +144,7 @@ export default Ember.TextField.extend({
|
|||
@observes("usernames")
|
||||
_clearInput: function () {
|
||||
if (arguments.length > 1) {
|
||||
if (Em.isEmpty(this.get("usernames"))) {
|
||||
if (isEmpty(this.get("usernames"))) {
|
||||
$(this.element).parent().find("a").click();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import Component from "@ember/component";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
export default Component.extend({
|
||||
actions: {
|
||||
perform() {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import WizardFieldValidator from "../../wizard/components/validator";
|
||||
import { deepMerge } from "discourse-common/lib/object";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import { cancel, later } from "@ember/runloop";
|
||||
import { A } from "@ember/array";
|
||||
import EmberObject, { computed } from "@ember/object";
|
||||
import { notEmpty, and, equal, empty } from "@ember/object/computed";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { and, equal, notEmpty } from "@ember/object/computed";
|
||||
import { categoryBadgeHTML } from "discourse/helpers/category-link";
|
||||
import { dasherize } from "@ember/string";
|
||||
|
||||
|
@ -16,7 +15,7 @@ export default WizardFieldValidator.extend({
|
|||
hasSimilarTopics: notEmpty("similarTopics"),
|
||||
hasNotSearched: equal("similarTopics", null),
|
||||
noSimilarTopics: computed("similarTopics", function () {
|
||||
return this.similarTopics !== null && this.similarTopics.length == 0;
|
||||
return this.similarTopics !== null && this.similarTopics.length === 0;
|
||||
}),
|
||||
showSimilarTopics: computed("typing", "hasSimilarTopics", function () {
|
||||
return this.hasSimilarTopics && !this.typing;
|
||||
|
@ -35,8 +34,9 @@ export default WizardFieldValidator.extend({
|
|||
|
||||
@discourseComputed("validation.categories")
|
||||
validationCategories(categoryIds) {
|
||||
if (categoryIds)
|
||||
if (categoryIds) {
|
||||
return categoryIds.map((id) => this.site.categoriesById[id]);
|
||||
}
|
||||
|
||||
return A();
|
||||
},
|
||||
|
@ -78,15 +78,18 @@ export default WizardFieldValidator.extend({
|
|||
|
||||
@discourseComputed("currentState")
|
||||
currentStateClass(currentState) {
|
||||
if (currentState) return `similar-topics-${dasherize(currentState)}`;
|
||||
if (currentState) {
|
||||
return `similar-topics-${dasherize(currentState)}`;
|
||||
}
|
||||
|
||||
return "similar-topics";
|
||||
},
|
||||
|
||||
@discourseComputed("currentState")
|
||||
currentStateKey(currentState) {
|
||||
if (currentState)
|
||||
if (currentState) {
|
||||
return `realtime_validations.similar_topics.${currentState}`;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
|
|
@ -4,22 +4,18 @@ import {
|
|||
on,
|
||||
} from "discourse-common/utils/decorators";
|
||||
import { findRawTemplate } from "discourse-common/lib/raw-templates";
|
||||
import { throttle } from "@ember/runloop";
|
||||
import { scheduleOnce, next } from "@ember/runloop";
|
||||
import {
|
||||
safariHacksDisabled,
|
||||
caretPosition,
|
||||
inCodeBlock,
|
||||
} from "discourse/lib/utilities";
|
||||
import { next, scheduleOnce, throttle } from "@ember/runloop";
|
||||
import { caretPosition, inCodeBlock } from "discourse/lib/utilities";
|
||||
import highlightSyntax from "discourse/lib/highlight-syntax";
|
||||
import { getToken } from "wizard/lib/ajax";
|
||||
import {
|
||||
validateUploadedFiles,
|
||||
displayErrorForUpload,
|
||||
getUploadMarkdown,
|
||||
uploadIcon,
|
||||
validateUploadedFiles,
|
||||
} from "discourse/lib/uploads";
|
||||
import { cacheShortUploadUrl } from "pretty-text/upload-short-url";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import { uploadIcon } from "discourse/lib/uploads";
|
||||
import WizardI18n from "../lib/wizard-i18n";
|
||||
|
||||
const uploadMarkdownResolvers = [];
|
||||
|
@ -78,8 +74,8 @@ export default ComposerEditor.extend({
|
|||
.join(",");
|
||||
},
|
||||
|
||||
@discourseComputed("currentUser")
|
||||
uploadIcon(currentUser) {
|
||||
@discourseComputed()
|
||||
uploadIcon() {
|
||||
return uploadIcon(false, this.siteSettings);
|
||||
},
|
||||
|
||||
|
@ -295,7 +291,7 @@ export default ComposerEditor.extend({
|
|||
shortcut: "K",
|
||||
trimLeading: true,
|
||||
unshift: true,
|
||||
sendAction: (event) => component.set("showHyperlinkBox", true),
|
||||
sendAction: () => component.set("showHyperlinkBox", true),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ export default Ember.Component.extend({
|
|||
[...value].reduce((result, v) => {
|
||||
let val =
|
||||
property === "id" ? Category.findById(v) : Category.findBySlug(v);
|
||||
if (val) result.push(val);
|
||||
if (val) {
|
||||
result.push(val);
|
||||
}
|
||||
return result;
|
||||
}, [])
|
||||
);
|
||||
|
|
|
@ -2,6 +2,7 @@ import CustomWizard from "../models/custom";
|
|||
|
||||
export default Ember.Component.extend({
|
||||
siteName: function () {
|
||||
/*eslint no-undef:0*/
|
||||
return Wizard.SiteSettings.title;
|
||||
}.property(),
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ export default Component.extend({
|
|||
},
|
||||
|
||||
documentClick(e) {
|
||||
if (this._state == "destroying") return;
|
||||
if (this._state === "destroying") {
|
||||
return;
|
||||
}
|
||||
let $target = $(e.target);
|
||||
|
||||
if (!$target.hasClass("show-topics")) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint no-undef: 0 */
|
||||
/* eslint no-undef: 0*/
|
||||
|
||||
import computed from "discourse-common/utils/decorators";
|
||||
import { siteDir, isRTL, isLTR } from "discourse/lib/text-direction";
|
||||
import { isLTR, isRTL, siteDir } from "discourse/lib/text-direction";
|
||||
import WizardI18n from "../lib/wizard-i18n";
|
||||
|
||||
export default Ember.TextField.extend({
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||
import I18n from "I18n";
|
||||
import Handlebars from "handlebars";
|
||||
|
||||
export default registerUnbound("char-counter", function (body, maxLength) {
|
||||
let bodyLength = body ? body.length : 0;
|
||||
|
@ -9,11 +10,11 @@ export default registerUnbound("char-counter", function (body, maxLength) {
|
|||
let isOverMax = bodyLength > maxLength ? "true" : "false";
|
||||
finalString = `<div class="body-length" data-length=${bodyLength} data-over-max=${isOverMax}>${bodyLength} / ${I18n.t(
|
||||
"wizard.x_characters",
|
||||
{ count: parseInt(maxLength) }
|
||||
{ count: parseInt(maxLength, 10) }
|
||||
)}</div>`;
|
||||
} else {
|
||||
finalString = `<div class="body-length">${I18n.t("wizard.x_characters", {
|
||||
count: parseInt(bodyLength),
|
||||
count: parseInt(bodyLength, 10),
|
||||
})}</div>`;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||
import { longDate, number, relativeAge } from "discourse/lib/formatter";
|
||||
import { longDate, relativeAge } from "discourse/lib/formatter";
|
||||
import Handlebars from "handlebars";
|
||||
|
||||
export default registerUnbound("date-node", function (dt) {
|
||||
if (typeof dt === "string") {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||
import Handlebars from "handlebars";
|
||||
|
||||
export default registerUnbound("dir-span", function (str) {
|
||||
return new Handlebars.SafeString(str);
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import { htmlHelper } from 'discourse-common/lib/helpers';
|
||||
import { htmlHelper } from "discourse-common/lib/helpers";
|
||||
|
||||
function renderSpinner(cssClass) {
|
||||
var html = "<div class='spinner";
|
||||
if (cssClass) { html += ' ' + cssClass; }
|
||||
if (cssClass) {
|
||||
html += " " + cssClass;
|
||||
}
|
||||
return html + "'></div>";
|
||||
}
|
||||
var spinnerHTML = renderSpinner();
|
||||
|
||||
export default htmlHelper(params => {
|
||||
export default htmlHelper((params) => {
|
||||
const hash = params.hash;
|
||||
return renderSpinner((hash && hash.size) ? hash.size : undefined);
|
||||
return renderSpinner(hash && hash.size ? hash.size : undefined);
|
||||
});
|
||||
|
||||
export { spinnerHTML, renderSpinner };
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { registerUnbound } from "discourse-common/lib/helpers";
|
||||
import Handlebars from "handlebars";
|
||||
|
||||
export default registerUnbound("plugin-outlet", function (attrs) {
|
||||
export default registerUnbound("plugin-outlet", function () {
|
||||
return new Handlebars.SafeString("");
|
||||
});
|
||||
|
|
|
@ -3,8 +3,10 @@ import discourseComputed from "discourse-common/utils/decorators";
|
|||
|
||||
export default {
|
||||
name: "custom-wizard-field",
|
||||
initialize(app) {
|
||||
if (window.location.pathname.indexOf("/w/") < 0) return;
|
||||
initialize() {
|
||||
if (window.location.pathname.indexOf("/w/") < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const FieldComponent = requirejs("wizard/components/wizard-field").default;
|
||||
const FieldModel = requirejs("wizard/models/wizard-field").default;
|
||||
|
@ -30,7 +32,9 @@ export default {
|
|||
inputComponentName: function () {
|
||||
const type = this.get("field.type");
|
||||
const id = this.get("field.id");
|
||||
if (["text_only"].includes(type)) return false;
|
||||
if (["text_only"].includes(type)) {
|
||||
return false;
|
||||
}
|
||||
return dasherize(type === "component" ? id : `wizard-field-${type}`);
|
||||
}.property("field.type", "field.id"),
|
||||
});
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
export default {
|
||||
name: "custom-wizard-step",
|
||||
initialize(app) {
|
||||
if (window.location.pathname.indexOf("/w/") < 0) return;
|
||||
initialize() {
|
||||
if (window.location.pathname.indexOf("/w/") < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const CustomWizard = requirejs(
|
||||
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
|
||||
|
@ -132,7 +134,9 @@ export default {
|
|||
|
||||
bannerImage: function () {
|
||||
const src = this.get("step.banner");
|
||||
if (!src) return;
|
||||
if (!src) {
|
||||
return;
|
||||
}
|
||||
return getUrl(src);
|
||||
}.property("step.banner"),
|
||||
|
||||
|
@ -166,7 +170,7 @@ export default {
|
|||
.finally(() => this.set("saving", false));
|
||||
},
|
||||
|
||||
keyPress(key) {},
|
||||
keyPress() {},
|
||||
|
||||
actions: {
|
||||
quit() {
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
export default {
|
||||
name: "custom-routes",
|
||||
initialize(app) {
|
||||
if (window.location.pathname.indexOf("/w/") < 0) return;
|
||||
if (window.location.pathname.indexOf("/w/") < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const EmberObject = requirejs("@ember/object").default;
|
||||
const Router = requirejs("wizard/router").default;
|
||||
const ApplicationRoute = requirejs("wizard/routes/application").default;
|
||||
const CustomWizard = requirejs(
|
||||
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
|
||||
).default;
|
||||
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
||||
const Store = requirejs("discourse/models/store").default;
|
||||
const registerRawHelpers = requirejs(
|
||||
|
@ -18,6 +17,7 @@ export default {
|
|||
.createHelperContext;
|
||||
const RawHandlebars = requirejs("discourse-common/lib/raw-handlebars")
|
||||
.default;
|
||||
const Handlebars = requirejs("handlebars").default;
|
||||
const Site = requirejs(
|
||||
"discourse/plugins/discourse-custom-wizard/wizard/models/site"
|
||||
).default;
|
||||
|
@ -36,10 +36,12 @@ export default {
|
|||
// IE11 Polyfill - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Polyfill
|
||||
if (!Object.entries) {
|
||||
Object.entries = function (obj) {
|
||||
var ownProps = Object.keys(obj),
|
||||
let ownProps = Object.keys(obj),
|
||||
i = ownProps.length,
|
||||
resArray = new Array(i); // preallocate the Array
|
||||
while (i--) resArray[i] = [ownProps[i], obj[ownProps[i]]];
|
||||
while (i--) {
|
||||
resArray[i] = [ownProps[i], obj[ownProps[i]]];
|
||||
}
|
||||
|
||||
return resArray;
|
||||
};
|
||||
|
@ -53,7 +55,7 @@ export default {
|
|||
});
|
||||
|
||||
const targets = ["controller", "component", "route", "model", "adapter"];
|
||||
|
||||
/*eslint no-undef: 0*/
|
||||
const siteSettings = Wizard.SiteSettings;
|
||||
app.register("site-settings:main", siteSettings, { instantiate: false });
|
||||
createHelperContext({ siteSettings });
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import loadScript from "./load-script";
|
||||
import { default as PrettyText } from "pretty-text/pretty-text";
|
||||
import Handlebars from "handlebars";
|
||||
|
||||
export function cook(text, options) {
|
||||
return new Handlebars.SafeString(new PrettyText(options).cook(text));
|
||||
|
|
|
@ -2,7 +2,7 @@ import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
|
|||
import { debounce } from "@ember/runloop";
|
||||
import getUrl from "discourse-common/lib/get-url";
|
||||
|
||||
var cache = {},
|
||||
let cache = {},
|
||||
cacheTopicId,
|
||||
cacheTime,
|
||||
currentTerm,
|
||||
|
@ -18,7 +18,7 @@ function performSearch(
|
|||
group,
|
||||
resultsFn
|
||||
) {
|
||||
var cached = cache[term];
|
||||
let cached = cache[term];
|
||||
if (cached) {
|
||||
resultsFn(cached);
|
||||
return;
|
||||
|
@ -37,7 +37,7 @@ function performSearch(
|
|||
},
|
||||
});
|
||||
|
||||
var returnVal = CANCELLED_STATUS;
|
||||
let returnVal = CANCELLED_STATUS;
|
||||
|
||||
oldSearch
|
||||
.then(function (r) {
|
||||
|
@ -59,7 +59,7 @@ function organizeResults(r, options) {
|
|||
return r;
|
||||
}
|
||||
|
||||
var exclude = options.exclude || [],
|
||||
let exclude = options.exclude || [],
|
||||
limit = options.limit || 5,
|
||||
users = [],
|
||||
emails = [],
|
||||
|
@ -87,8 +87,9 @@ function organizeResults(r, options) {
|
|||
if (
|
||||
results.length > limit &&
|
||||
options.term.toLowerCase() !== g.name.toLowerCase()
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (exclude.indexOf(g.name) === -1) {
|
||||
groups.push(g);
|
||||
results.push(g);
|
||||
|
@ -104,7 +105,7 @@ function organizeResults(r, options) {
|
|||
}
|
||||
|
||||
export default function userSearch(options) {
|
||||
var term = options.term || "",
|
||||
let term = options.term || "",
|
||||
includeGroups = options.includeGroups,
|
||||
includeMentionableGroups = options.includeMentionableGroups,
|
||||
includeMessageableGroups = options.includeMessageableGroups,
|
||||
|
@ -131,7 +132,7 @@ export default function userSearch(options) {
|
|||
|
||||
cacheTopicId = topicId;
|
||||
|
||||
var clearPromise = setTimeout(function () {
|
||||
let clearPromise = setTimeout(function () {
|
||||
resolve(CANCELLED_STATUS);
|
||||
}, 5000);
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ const translationExists = (key) => {
|
|||
|
||||
const WizardI18n = (key, params = {}) => {
|
||||
const themeId = getThemeId();
|
||||
if (!themeId) return I18n.t(key, params);
|
||||
if (!themeId) {
|
||||
return I18n.t(key, params);
|
||||
}
|
||||
|
||||
const themeKey = `theme_translations.${themeId}.${key}`;
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ const CustomWizard = EmberObject.extend({
|
|||
totalSteps: (length) => length,
|
||||
|
||||
skip() {
|
||||
if (this.required && !this.completed && this.permitted) return;
|
||||
if (this.required && !this.completed && this.permitted) {
|
||||
return;
|
||||
}
|
||||
CustomWizard.skip(this.id);
|
||||
},
|
||||
});
|
||||
|
@ -35,7 +37,9 @@ export function findCustomWizard(wizardId, params = {}) {
|
|||
let url = `/w/${wizardId}`;
|
||||
|
||||
let paramKeys = Object.keys(params).filter((k) => {
|
||||
if (k === "wizard_id") return false;
|
||||
if (k === "wizard_id") {
|
||||
return false;
|
||||
}
|
||||
return !!params[k];
|
||||
});
|
||||
|
||||
|
@ -51,7 +55,9 @@ export function findCustomWizard(wizardId, params = {}) {
|
|||
|
||||
return ajax({ url, cache: false, dataType: "json" }).then((result) => {
|
||||
const wizard = result;
|
||||
if (!wizard) return null;
|
||||
if (!wizard) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!wizard.completed) {
|
||||
wizard.steps = wizard.steps.map((step) => {
|
||||
|
@ -62,7 +68,7 @@ export function findCustomWizard(wizardId, params = {}) {
|
|||
});
|
||||
|
||||
let tabindex = 1;
|
||||
stepObj.fields.forEach((f, i) => {
|
||||
stepObj.fields.forEach((f) => {
|
||||
f.tabindex = tabindex;
|
||||
|
||||
if (["date_time"].includes(f.type)) {
|
||||
|
|
|
@ -13,7 +13,9 @@ export default Ember.Route.extend({
|
|||
},
|
||||
|
||||
afterModel(model) {
|
||||
if (model.completed) return this.transitionTo("index");
|
||||
if (model.completed) {
|
||||
return this.transitionTo("index");
|
||||
}
|
||||
return model.set("wizardId", this.modelFor("custom").id);
|
||||
},
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint no-undef: 0 */
|
||||
/* eslint no-undef: 0*/
|
||||
|
||||
import { findCustomWizard } from "../models/custom";
|
||||
import { ajax } from "wizard/lib/ajax";
|
||||
|
|
Laden …
In neuem Issue referenzieren