Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-25 18:50:27 +01:00
Refactor wizard client and add tests
Dieser Commit ist enthalten in:
Ursprung
b20b8ce333
Commit
8893e6caf1
98 geänderte Dateien mit 2834 neuen und 1203 gelöschten Zeilen
|
@ -1,6 +0,0 @@
|
||||||
/* eslint no-undef: 0*/
|
|
||||||
window.Discourse = {};
|
|
||||||
window.Wizard = {};
|
|
||||||
Wizard.SiteSettings = {};
|
|
||||||
Discourse.__widget_helpers = {};
|
|
||||||
Discourse.SiteSettings = Wizard.SiteSettings;
|
|
|
@ -1,4 +1,4 @@
|
||||||
(function () {
|
(function () {
|
||||||
let wizard = require("discourse/plugins/discourse-custom-wizard/wizard/custom-wizard").default.create();
|
let wizard = require("discourse/plugins/discourse-custom-wizard/wizard/application").default.create();
|
||||||
wizard.start();
|
wizard.start();
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
//= require_tree_discourse truth-helpers/addon
|
||||||
|
//= require_tree_discourse discourse-common/addon
|
||||||
|
//= require_tree_discourse select-kit/addon
|
||||||
|
//= require_tree_discourse wizard/lib
|
||||||
|
//= require_tree_discourse wizard/mixins
|
||||||
//= require_tree_discourse discourse/app/lib
|
//= require_tree_discourse discourse/app/lib
|
||||||
//= require_tree_discourse discourse/app/mixins
|
//= require_tree_discourse discourse/app/mixins
|
||||||
|
|
||||||
//= require discourse/app/adapters/rest
|
//= require discourse/app/adapters/rest
|
||||||
|
|
||||||
//= require message-bus
|
//= require message-bus
|
||||||
|
|
||||||
//= require_tree_discourse discourse/app/models
|
//= require_tree_discourse discourse/app/models
|
||||||
|
|
||||||
//= require discourse/app/helpers/category-link
|
//= require discourse/app/helpers/category-link
|
||||||
|
@ -12,9 +15,6 @@
|
||||||
//= require discourse/app/helpers/format-username
|
//= require discourse/app/helpers/format-username
|
||||||
//= require discourse/app/helpers/share-url
|
//= require discourse/app/helpers/share-url
|
||||||
//= require discourse/app/helpers/decorate-username-selector
|
//= require discourse/app/helpers/decorate-username-selector
|
||||||
//= require discourse-common/addon/helpers/component-for-collection
|
|
||||||
//= require discourse-common/addon/helpers/component-for-row
|
|
||||||
//= require discourse-common/addon/lib/raw-templates
|
|
||||||
//= require discourse/app/helpers/discourse-tag
|
//= require discourse/app/helpers/discourse-tag
|
||||||
|
|
||||||
//= require discourse/app/services/app-events
|
//= require discourse/app/services/app-events
|
||||||
|
@ -59,7 +59,6 @@
|
||||||
//= require polyfills
|
//= require polyfills
|
||||||
|
|
||||||
//= require markdown-it-bundle
|
//= require markdown-it-bundle
|
||||||
//= require lodash.js
|
|
||||||
//= require template_include.js
|
//= require template_include.js
|
||||||
//= require itsatrap.js
|
//= require itsatrap.js
|
||||||
//= require caret_position.js
|
//= require caret_position.js
|
||||||
|
@ -69,11 +68,11 @@
|
||||||
//= require bootbox.js
|
//= require bootbox.js
|
||||||
//= require discourse-shims
|
//= require discourse-shims
|
||||||
|
|
||||||
//= require ./wizard/custom-wizard
|
//= require ./wizard/application
|
||||||
|
//= require ./wizard/router
|
||||||
//= require_tree ./wizard/components
|
//= require_tree ./wizard/components
|
||||||
//= require_tree ./wizard/controllers
|
//= require_tree ./wizard/controllers
|
||||||
//= require_tree ./wizard/helpers
|
//= require_tree ./wizard/helpers
|
||||||
//= require_tree ./wizard/initializers
|
|
||||||
//= require_tree ./wizard/lib
|
//= require_tree ./wizard/lib
|
||||||
//= require_tree ./wizard/models
|
//= require_tree ./wizard/models
|
||||||
//= require_tree ./wizard/routes
|
//= require_tree ./wizard/routes
|
||||||
|
|
16
assets/javascripts/wizard-qunit.js
Normale Datei
16
assets/javascripts/wizard-qunit.js
Normale Datei
|
@ -0,0 +1,16 @@
|
||||||
|
//= require route-recognizer
|
||||||
|
//= require fake_xml_http_request
|
||||||
|
//= require pretender
|
||||||
|
//= require qunit
|
||||||
|
//= require ember-qunit
|
||||||
|
//= require test-shims
|
||||||
|
//= require jquery.debug
|
||||||
|
//= require ember.debug
|
||||||
|
//= require ember-template-compiler
|
||||||
|
|
||||||
|
//= require_tree ./wizard/tests/fixtures
|
||||||
|
//= require ./wizard/tests/pretender
|
||||||
|
//= require_tree ./wizard/tests/helpers
|
||||||
|
//= require_tree ./wizard/tests/acceptance
|
||||||
|
|
||||||
|
//= require ./wizard/tests/bootstrap
|
19
assets/javascripts/wizard/application.js.es6
Normale Datei
19
assets/javascripts/wizard/application.js.es6
Normale Datei
|
@ -0,0 +1,19 @@
|
||||||
|
import { buildResolver } from "discourse-common/resolver";
|
||||||
|
import Application from "@ember/application";
|
||||||
|
import WizardInitializer from "./lib/initialize/wizard";
|
||||||
|
import { isTesting } from "discourse-common/config/environment";
|
||||||
|
|
||||||
|
export default Application.extend({
|
||||||
|
rootElement: "#custom-wizard-main",
|
||||||
|
Resolver: buildResolver("discourse/plugins/discourse-custom-wizard/wizard"),
|
||||||
|
|
||||||
|
customEvents: {
|
||||||
|
paste: "paste",
|
||||||
|
},
|
||||||
|
|
||||||
|
start() {
|
||||||
|
if (!isTesting()) {
|
||||||
|
this.initializer(WizardInitializer);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,6 +1,6 @@
|
||||||
import {
|
import {
|
||||||
default as computed,
|
default as computed,
|
||||||
observes,
|
observes
|
||||||
} from "discourse-common/utils/decorators";
|
} from "discourse-common/utils/decorators";
|
||||||
import { renderAvatar } from "discourse/helpers/user-avatar";
|
import { renderAvatar } from "discourse/helpers/user-avatar";
|
||||||
import userSearch from "../lib/user-search";
|
import userSearch from "../lib/user-search";
|
||||||
|
@ -55,7 +55,6 @@ export default Ember.TextField.extend({
|
||||||
let self = this,
|
let self = this,
|
||||||
selected = [],
|
selected = [],
|
||||||
groups = [],
|
groups = [],
|
||||||
currentUser = this.currentUser,
|
|
||||||
includeMentionableGroups =
|
includeMentionableGroups =
|
||||||
this.get("includeMentionableGroups") === "true",
|
this.get("includeMentionableGroups") === "true",
|
||||||
includeMessageableGroups =
|
includeMessageableGroups =
|
||||||
|
@ -66,13 +65,8 @@ export default Ember.TextField.extend({
|
||||||
function excludedUsernames() {
|
function excludedUsernames() {
|
||||||
// hack works around some issues with allowAny eventing
|
// hack works around some issues with allowAny eventing
|
||||||
const usernames = self.get("single") ? [] : selected;
|
const usernames = self.get("single") ? [] : selected;
|
||||||
|
|
||||||
if (currentUser && self.get("excludeCurrentUser")) {
|
|
||||||
return usernames.concat([currentUser.get("username")]);
|
|
||||||
}
|
|
||||||
return usernames;
|
return usernames;
|
||||||
}
|
}
|
||||||
|
|
||||||
$(this.element)
|
$(this.element)
|
||||||
.val(this.get("usernames"))
|
.val(this.get("usernames"))
|
||||||
.autocomplete({
|
.autocomplete({
|
||||||
|
@ -84,7 +78,6 @@ export default Ember.TextField.extend({
|
||||||
|
|
||||||
dataSource(term) {
|
dataSource(term) {
|
||||||
const termRegex = /[^a-zA-Z0-9_\-\.@\+]/;
|
const termRegex = /[^a-zA-Z0-9_\-\.@\+]/;
|
||||||
|
|
||||||
let results = userSearch({
|
let results = userSearch({
|
||||||
term: term.replace(termRegex, ""),
|
term: term.replace(termRegex, ""),
|
||||||
topicId: self.get("topicId"),
|
topicId: self.get("topicId"),
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/field-validators',
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
perform() {
|
perform() {
|
||||||
this.appEvents.trigger("custom-wizard:validate");
|
this.appEvents.trigger("custom-wizard:validate");
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { dasherize } from "@ember/string";
|
||||||
|
|
||||||
export default WizardFieldValidator.extend({
|
export default WizardFieldValidator.extend({
|
||||||
classNames: ["similar-topics-validator"],
|
classNames: ["similar-topics-validator"],
|
||||||
|
layoutName: 'wizard/templates/components/similar-topics-validator',
|
||||||
similarTopics: null,
|
similarTopics: null,
|
||||||
hasInput: notEmpty("field.value"),
|
hasInput: notEmpty("field.value"),
|
||||||
hasSimilarTopics: notEmpty("similarTopics"),
|
hasSimilarTopics: notEmpty("similarTopics"),
|
||||||
|
|
|
@ -6,11 +6,12 @@ import { getToken } from "wizard/lib/ajax";
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ["validator"],
|
classNames: ["validator"],
|
||||||
classNameBindings: ["isValid", "isInvalid"],
|
classNameBindings: ["isValid", "isInvalid"],
|
||||||
|
layoutName: 'wizard/templates/components/validator',
|
||||||
validMessageKey: null,
|
validMessageKey: null,
|
||||||
invalidMessageKey: null,
|
invalidMessageKey: null,
|
||||||
isValid: null,
|
isValid: null,
|
||||||
isInvalid: equal("isValid", false),
|
isInvalid: equal("isValid", false),
|
||||||
layoutName: "components/validator", // useful for sharing the template with extending components
|
layoutName: "wizard/templates/components/validator",
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { uploadIcon } from "discourse/lib/uploads";
|
||||||
import { dasherize } from "@ember/string";
|
import { dasherize } from "@ember/string";
|
||||||
|
|
||||||
export default ComposerEditor.extend({
|
export default ComposerEditor.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-composer-editor',
|
||||||
classNameBindings: ["fieldClass"],
|
classNameBindings: ["fieldClass"],
|
||||||
allowUpload: true,
|
allowUpload: true,
|
||||||
showLink: false,
|
showLink: false,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import Component from "@ember/component";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ["wizard-composer-hyperlink"],
|
classNames: ["wizard-composer-hyperlink"],
|
||||||
|
layoutName: 'wizard/templates/components/wizard-composer-hyperlink',
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
addLink() {
|
addLink() {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default DateInput.extend({
|
export default DateInput.extend({
|
||||||
useNativePicker: false,
|
useNativePicker: false,
|
||||||
|
layoutName: 'wizard/templates/components/wizard-date-input',
|
||||||
|
|
||||||
@discourseComputed()
|
@discourseComputed()
|
||||||
placeholder() {
|
placeholder() {
|
||||||
|
|
|
@ -2,6 +2,8 @@ import DateTimeInput from "discourse/components/date-time-input";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default DateTimeInput.extend({
|
export default DateTimeInput.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-date-time-input',
|
||||||
|
|
||||||
@discourseComputed("timeFirst", "tabindex")
|
@discourseComputed("timeFirst", "tabindex")
|
||||||
timeTabindex(timeFirst, tabindex) {
|
timeTabindex(timeFirst, tabindex) {
|
||||||
return timeFirst ? tabindex : tabindex + 1;
|
return timeFirst ? tabindex : tabindex + 1;
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { observes } from "discourse-common/utils/decorators";
|
||||||
import Category from "discourse/models/category";
|
import Category from "discourse/models/category";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-category',
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
const property = this.field.property || "id";
|
const property = this.field.property || "id";
|
||||||
const value = this.field.value;
|
const value = this.field.value;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-checkbox'
|
||||||
|
});
|
|
@ -7,6 +7,8 @@ import { ajax } from "discourse/lib/ajax";
|
||||||
import { on } from "discourse-common/utils/decorators";
|
import { on } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-composer-preview',
|
||||||
|
|
||||||
@on("init")
|
@on("init")
|
||||||
updatePreview() {
|
updatePreview() {
|
||||||
if (this.isDestroyed) {
|
if (this.isDestroyed) {
|
||||||
|
|
|
@ -5,6 +5,8 @@ import {
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-composer',
|
||||||
|
|
||||||
showPreview: false,
|
showPreview: false,
|
||||||
classNameBindings: [
|
classNameBindings: [
|
||||||
":wizard-field-composer",
|
":wizard-field-composer",
|
||||||
|
|
|
@ -2,6 +2,8 @@ import Component from "@ember/component";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-date-time',
|
||||||
|
|
||||||
@observes("dateTime")
|
@observes("dateTime")
|
||||||
setValue() {
|
setValue() {
|
||||||
this.set("field.value", this.dateTime.format(this.field.format));
|
this.set("field.value", this.dateTime.format(this.field.format));
|
||||||
|
|
|
@ -2,6 +2,8 @@ import Component from "@ember/component";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-date',
|
||||||
|
|
||||||
@observes("date")
|
@observes("date")
|
||||||
setValue() {
|
setValue() {
|
||||||
this.set("field.value", this.date.format(this.field.format));
|
this.set("field.value", this.date.format(this.field.format));
|
||||||
|
|
15
assets/javascripts/wizard/components/wizard-field-dropdown.js.es6
Normale Datei
15
assets/javascripts/wizard/components/wizard-field-dropdown.js.es6
Normale Datei
|
@ -0,0 +1,15 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-dropdown',
|
||||||
|
|
||||||
|
keyPress(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onChangeValue(value) {
|
||||||
|
this.set("field.value", value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
5
assets/javascripts/wizard/components/wizard-field-group.js.es6
Normale Datei
5
assets/javascripts/wizard/components/wizard-field-group.js.es6
Normale Datei
|
@ -0,0 +1,5 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-group'
|
||||||
|
});
|
5
assets/javascripts/wizard/components/wizard-field-number.js.es6
Normale Datei
5
assets/javascripts/wizard/components/wizard-field-number.js.es6
Normale Datei
|
@ -0,0 +1,5 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-number'
|
||||||
|
});
|
5
assets/javascripts/wizard/components/wizard-field-tag.js.es6
Normale Datei
5
assets/javascripts/wizard/components/wizard-field-tag.js.es6
Normale Datei
|
@ -0,0 +1,5 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-tag'
|
||||||
|
});
|
9
assets/javascripts/wizard/components/wizard-field-text.js.es6
Normale Datei
9
assets/javascripts/wizard/components/wizard-field-text.js.es6
Normale Datei
|
@ -0,0 +1,9 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-text',
|
||||||
|
|
||||||
|
keyPress(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-textarea',
|
||||||
|
|
||||||
|
keyPress(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
},
|
||||||
|
});
|
|
@ -2,6 +2,8 @@ import Component from "@ember/component";
|
||||||
import { observes } from "discourse-common/utils/decorators";
|
import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-time',
|
||||||
|
|
||||||
@observes("time")
|
@observes("time")
|
||||||
setValue() {
|
setValue() {
|
||||||
this.set("field.value", this.time.format(this.field.format));
|
this.set("field.value", this.time.format(this.field.format));
|
||||||
|
|
|
@ -3,12 +3,16 @@ import Component from "@ember/component";
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
|
|
||||||
export default Component.extend(UppyUploadMixin, {
|
export default Component.extend(UppyUploadMixin, {
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-upload',
|
||||||
classNames: ["wizard-field-upload"],
|
classNames: ["wizard-field-upload"],
|
||||||
classNameBindings: ["isImage"],
|
classNameBindings: ["isImage"],
|
||||||
uploading: false,
|
uploading: false,
|
||||||
type: computed(function () {
|
type: computed(function () {
|
||||||
return `wizard_${this.field.id}`;
|
return `wizard_${this.field.id}`;
|
||||||
}),
|
}),
|
||||||
|
id: computed(function () {
|
||||||
|
return `wizard_field_upload_${this.field.id}`;
|
||||||
|
}),
|
||||||
isImage: computed("field.value.extension", function () {
|
isImage: computed("field.value.extension", function () {
|
||||||
return (
|
return (
|
||||||
this.field.value &&
|
this.field.value &&
|
||||||
|
|
5
assets/javascripts/wizard/components/wizard-field-url.js.es6
Normale Datei
5
assets/javascripts/wizard/components/wizard-field-url.js.es6
Normale Datei
|
@ -0,0 +1,5 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-url'
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field-user-selector'
|
||||||
|
});
|
34
assets/javascripts/wizard/components/wizard-field.js.es6
Normale Datei
34
assets/javascripts/wizard/components/wizard-field.js.es6
Normale Datei
|
@ -0,0 +1,34 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
import { dasherize } from "@ember/string";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import { cook } from "discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-field',
|
||||||
|
classNameBindings: [":wizard-field", "typeClasses", "field.invalid", "field.id"],
|
||||||
|
|
||||||
|
@discourseComputed("field.type", "field.id")
|
||||||
|
typeClasses: (type, id) =>
|
||||||
|
`${dasherize(type)}-field ${dasherize(type)}-${dasherize(id)}`,
|
||||||
|
|
||||||
|
@discourseComputed("field.id")
|
||||||
|
fieldClass: (id) => `field-${dasherize(id)} wizard-focusable`,
|
||||||
|
|
||||||
|
@discourseComputed("field.type", "field.id")
|
||||||
|
inputComponentName(type, id) {
|
||||||
|
if (["text_only"].includes(type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return dasherize(type === "component" ? id : `wizard-field-${type}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("field.translatedDescription")
|
||||||
|
cookedDescription(description) {
|
||||||
|
return cook(description);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("field.type")
|
||||||
|
textType(fieldType) {
|
||||||
|
return ["text", "textarea"].includes(fieldType);
|
||||||
|
},
|
||||||
|
});
|
|
@ -3,6 +3,7 @@ import { computed } from "@ember/object";
|
||||||
import { makeArray } from "discourse-common/lib/helpers";
|
import { makeArray } from "discourse-common/lib/helpers";
|
||||||
|
|
||||||
export default ComboBox.extend({
|
export default ComboBox.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-group-selector',
|
||||||
content: computed("groups.[]", "field.content.[]", function () {
|
content: computed("groups.[]", "field.content.[]", function () {
|
||||||
const whitelist = makeArray(this.field.content);
|
const whitelist = makeArray(this.field.content);
|
||||||
return this.groups
|
return this.groups
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
import CustomWizard from "../models/custom";
|
import CustomWizard from "../models/wizard";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import Component from "@ember/component";
|
||||||
|
import { dasherize } from "@ember/string";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Component.extend({
|
||||||
siteName: function () {
|
classNameBindings: [':wizard-no-access', 'reasonClass'],
|
||||||
/*eslint no-undef:0*/
|
layoutName: 'wizard/templates/components/wizard-no-access',
|
||||||
return Wizard.SiteSettings.title;
|
|
||||||
}.property(),
|
@discourseComputed('reason')
|
||||||
|
reasonClass(reason) {
|
||||||
|
return dasherize(reason);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed
|
||||||
|
siteName() {
|
||||||
|
return (this.siteSettings.title || '');
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
skip() {
|
skip() {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { observes } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ["wizard-similar-topics"],
|
classNames: ["wizard-similar-topics"],
|
||||||
|
layoutName: 'wizard/templates/components/wizard-similar-topics',
|
||||||
showTopics: true,
|
showTopics: true,
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
|
|
9
assets/javascripts/wizard/components/wizard-step-form.js.es6
Normale Datei
9
assets/javascripts/wizard/components/wizard-step-form.js.es6
Normale Datei
|
@ -0,0 +1,9 @@
|
||||||
|
import Component from "@ember/component";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
classNameBindings: [":wizard-step-form", "customStepClass"],
|
||||||
|
|
||||||
|
@discourseComputed("step.id")
|
||||||
|
customStepClass: (stepId) => `wizard-step-${stepId}`,
|
||||||
|
});
|
247
assets/javascripts/wizard/components/wizard-step.js.es6
Normale Datei
247
assets/javascripts/wizard/components/wizard-step.js.es6
Normale Datei
|
@ -0,0 +1,247 @@
|
||||||
|
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||||
|
import Component from "@ember/component";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import { schedule } from "@ember/runloop";
|
||||||
|
import { cook } from "discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite";
|
||||||
|
import { updateCachedWizard } from "discourse/plugins/discourse-custom-wizard/wizard/models/wizard";
|
||||||
|
import { alias, not } from "@ember/object/computed";
|
||||||
|
import CustomWizard from "../models/wizard";
|
||||||
|
|
||||||
|
const alreadyWarned = {};
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-step',
|
||||||
|
classNameBindings: [":wizard-step", "step.id"],
|
||||||
|
saving: null,
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.set("stylingDropdown", {});
|
||||||
|
},
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.autoFocus();
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.index", "wizard.required")
|
||||||
|
showQuitButton: (index, required) => (index === 0 && !required),
|
||||||
|
|
||||||
|
showNextButton: not("step.final"),
|
||||||
|
showDoneButton: alias("step.final"),
|
||||||
|
|
||||||
|
@discourseComputed("step.translatedTitle")
|
||||||
|
cookedTitle(title) {
|
||||||
|
return cook(title);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.translatedDescription")
|
||||||
|
cookedDescription(description) {
|
||||||
|
return cook(description);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed(
|
||||||
|
"step.index",
|
||||||
|
"step.displayIndex",
|
||||||
|
"wizard.totalSteps",
|
||||||
|
"wizard.completed"
|
||||||
|
)
|
||||||
|
showFinishButton: (index, displayIndex, total, completed) => {
|
||||||
|
return index !== 0 && displayIndex !== total && completed;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.index")
|
||||||
|
showBackButton: (index) => index > 0,
|
||||||
|
|
||||||
|
@discourseComputed("step.banner")
|
||||||
|
bannerImage(src) {
|
||||||
|
if (!src) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return getUrl(src);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.id")
|
||||||
|
bannerAndDescriptionClass(id) {
|
||||||
|
return `wizard-banner-and-description wizard-banner-and-description-${id}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.fields.[]")
|
||||||
|
primaryButtonIndex(fields) {
|
||||||
|
return fields.length + 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.fields.[]")
|
||||||
|
secondaryButtonIndex(fields) {
|
||||||
|
return fields.length + 2;
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("step.id")
|
||||||
|
_stepChanged() {
|
||||||
|
this.set("saving", false);
|
||||||
|
this.autoFocus();
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("step.message")
|
||||||
|
_handleMessage: function () {
|
||||||
|
const message = this.get("step.message");
|
||||||
|
this.sendAction("showMessage", message);
|
||||||
|
},
|
||||||
|
|
||||||
|
keyPress(event) {
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
if (this.showDoneButton) {
|
||||||
|
this.send("quit");
|
||||||
|
} else {
|
||||||
|
this.send("nextStep");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.index", "wizard.totalSteps")
|
||||||
|
barStyle(displayIndex, totalSteps) {
|
||||||
|
let ratio = parseFloat(displayIndex) / parseFloat(totalSteps - 1);
|
||||||
|
if (ratio < 0) {
|
||||||
|
ratio = 0;
|
||||||
|
}
|
||||||
|
if (ratio > 1) {
|
||||||
|
ratio = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return htmlSafe(`width: ${ratio * 200}px`);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("step.fields")
|
||||||
|
includeSidebar(fields) {
|
||||||
|
return !!fields.findBy("show_in_sidebar");
|
||||||
|
},
|
||||||
|
|
||||||
|
autoFocus() {
|
||||||
|
schedule("afterRender", () => {
|
||||||
|
const $invalid = $(
|
||||||
|
".wizard-field.invalid:nth-of-type(1) .wizard-focusable"
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($invalid.length) {
|
||||||
|
return $invalid.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".wizard-focusable:first").focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
animateInvalidFields() {
|
||||||
|
schedule("afterRender", () => {
|
||||||
|
let $element = $(
|
||||||
|
".invalid input[type=text],.invalid textarea,.invalid input[type=checkbox],.invalid .select-kit"
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($element.length) {
|
||||||
|
$([document.documentElement, document.body]).animate(
|
||||||
|
{
|
||||||
|
scrollTop: $element.offset().top - 200,
|
||||||
|
},
|
||||||
|
400,
|
||||||
|
function () {
|
||||||
|
$element.wiggle(2, 100);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
advance() {
|
||||||
|
this.set("saving", true);
|
||||||
|
this.get("step")
|
||||||
|
.save()
|
||||||
|
.then((response) => {
|
||||||
|
updateCachedWizard(CustomWizard.build(response["wizard"]));
|
||||||
|
|
||||||
|
if (response["final"]) {
|
||||||
|
CustomWizard.finished(response);
|
||||||
|
} else {
|
||||||
|
this.sendAction("goNext", response);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => this.animateInvalidFields())
|
||||||
|
.finally(() => this.set("saving", false));
|
||||||
|
},
|
||||||
|
|
||||||
|
keyPress() {},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
quit() {
|
||||||
|
this.get("wizard").skip();
|
||||||
|
},
|
||||||
|
|
||||||
|
done() {
|
||||||
|
this.send("nextStep");
|
||||||
|
},
|
||||||
|
|
||||||
|
showMessage(message) {
|
||||||
|
this.sendAction("showMessage", message);
|
||||||
|
},
|
||||||
|
|
||||||
|
stylingDropdownChanged(id, value) {
|
||||||
|
this.set("stylingDropdown", { id, value });
|
||||||
|
},
|
||||||
|
|
||||||
|
exitEarly() {
|
||||||
|
const step = this.step;
|
||||||
|
step.validate();
|
||||||
|
|
||||||
|
if (step.get("valid")) {
|
||||||
|
this.set("saving", true);
|
||||||
|
|
||||||
|
step
|
||||||
|
.save()
|
||||||
|
.then(() => this.send("quit"))
|
||||||
|
.finally(() => this.set("saving", false));
|
||||||
|
} else {
|
||||||
|
this.autoFocus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
backStep() {
|
||||||
|
if (this.saving) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.goBack();
|
||||||
|
},
|
||||||
|
|
||||||
|
nextStep() {
|
||||||
|
if (this.saving) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const step = this.step;
|
||||||
|
const result = step.validate();
|
||||||
|
|
||||||
|
if (result.warnings.length) {
|
||||||
|
const unwarned = result.warnings.filter((w) => !alreadyWarned[w]);
|
||||||
|
if (unwarned.length) {
|
||||||
|
unwarned.forEach((w) => (alreadyWarned[w] = true));
|
||||||
|
return window.bootbox.confirm(
|
||||||
|
unwarned.map((w) => I18n.t(`wizard.${w}`)).join("\n"),
|
||||||
|
I18n.t("no_value"),
|
||||||
|
I18n.t("yes_value"),
|
||||||
|
(confirmed) => {
|
||||||
|
if (confirmed) {
|
||||||
|
this.advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (step.get("valid")) {
|
||||||
|
this.advance();
|
||||||
|
} else {
|
||||||
|
this.autoFocus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,5 +1,3 @@
|
||||||
/* eslint no-undef: 0*/
|
|
||||||
|
|
||||||
import computed from "discourse-common/utils/decorators";
|
import computed from "discourse-common/utils/decorators";
|
||||||
import { isLTR, isRTL, siteDir } from "discourse/lib/text-direction";
|
import { isLTR, isRTL, siteDir } from "discourse/lib/text-direction";
|
||||||
import WizardI18n from "../lib/wizard-i18n";
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
@ -15,7 +13,7 @@ export default Ember.TextField.extend({
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
dir() {
|
dir() {
|
||||||
if (Wizard.SiteSettings.support_mixed_text_direction) {
|
if (this.siteSettings.support_mixed_text_direction) {
|
||||||
let val = this.value;
|
let val = this.value;
|
||||||
if (val) {
|
if (val) {
|
||||||
return isRTL(val) ? "rtl" : "ltr";
|
return isRTL(val) ? "rtl" : "ltr";
|
||||||
|
@ -26,7 +24,7 @@ export default Ember.TextField.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
keyUp() {
|
keyUp() {
|
||||||
if (Wizard.SiteSettings.support_mixed_text_direction) {
|
if (this.siteSettings.support_mixed_text_direction) {
|
||||||
let val = this.value;
|
let val = this.value;
|
||||||
if (isRTL(val)) {
|
if (isRTL(val)) {
|
||||||
this.set("dir", "rtl");
|
this.set("dir", "rtl");
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
import TimeInput from "discourse/components/time-input";
|
import TimeInput from "discourse/components/time-input";
|
||||||
|
|
||||||
export default TimeInput.extend();
|
export default TimeInput.extend({
|
||||||
|
layoutName: 'wizard/templates/components/wizard-time-input'
|
||||||
|
});
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
export default Ember.Controller.extend({
|
|
||||||
queryParams: ["reset"],
|
|
||||||
});
|
|
|
@ -1,7 +1,10 @@
|
||||||
import StepController from "wizard/controllers/step";
|
import Controller from "@ember/controller";
|
||||||
import getUrl from "discourse-common/lib/get-url";
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
|
|
||||||
export default StepController.extend({
|
export default Controller.extend({
|
||||||
|
wizard: null,
|
||||||
|
step: null,
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
goNext(response) {
|
goNext(response) {
|
||||||
let nextStepId = response["next_step_id"];
|
let nextStepId = response["next_step_id"];
|
||||||
|
@ -12,12 +15,12 @@ export default StepController.extend({
|
||||||
const wizardId = this.get("wizard.id");
|
const wizardId = this.get("wizard.id");
|
||||||
window.location.href = getUrl(`/w/${wizardId}/steps/${nextStepId}`);
|
window.location.href = getUrl(`/w/${wizardId}/steps/${nextStepId}`);
|
||||||
} else {
|
} else {
|
||||||
this.transitionToRoute("custom.step", nextStepId);
|
this.transitionToRoute("step", nextStepId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
goBack() {
|
goBack() {
|
||||||
this.transitionToRoute("custom.step", this.get("step.previous"));
|
this.transitionToRoute("step", this.get("step.previous"));
|
||||||
},
|
},
|
||||||
|
|
||||||
showMessage(message) {
|
showMessage(message) {
|
24
assets/javascripts/wizard/controllers/wizard-index.js.es6
Normale Datei
24
assets/javascripts/wizard/controllers/wizard-index.js.es6
Normale Datei
|
@ -0,0 +1,24 @@
|
||||||
|
import Controller from "@ember/controller";
|
||||||
|
import { or } from "@ember/object/computed";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
|
const reasons = {
|
||||||
|
noWizard: "none",
|
||||||
|
requiresLogin: "requires_login",
|
||||||
|
notPermitted: "not_permitted",
|
||||||
|
completed: "completed"
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Controller.extend({
|
||||||
|
noAccess: or('noWizard', 'requiresLogin', 'notPermitted', 'completed'),
|
||||||
|
|
||||||
|
@discourseComputed('noAccessReason')
|
||||||
|
noAccessI18nKey(reason) {
|
||||||
|
return reason ? `wizard.${reasons[reason]}` : 'wizard.none';
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed
|
||||||
|
noAccessReason() {
|
||||||
|
return Object.keys(reasons).find(reason => this.get(reason));
|
||||||
|
}
|
||||||
|
});
|
5
assets/javascripts/wizard/controllers/wizard.js.es6
Normale Datei
5
assets/javascripts/wizard/controllers/wizard.js.es6
Normale Datei
|
@ -0,0 +1,5 @@
|
||||||
|
import Controller from "@ember/controller";
|
||||||
|
|
||||||
|
export default Controller.extend({
|
||||||
|
queryParams: ["reset"],
|
||||||
|
});
|
|
@ -1,39 +0,0 @@
|
||||||
import { buildResolver } from "discourse-common/resolver";
|
|
||||||
|
|
||||||
export default Ember.Application.extend({
|
|
||||||
rootElement: "#custom-wizard-main",
|
|
||||||
Resolver: buildResolver("wizard"),
|
|
||||||
|
|
||||||
customEvents: {
|
|
||||||
paste: "paste",
|
|
||||||
},
|
|
||||||
|
|
||||||
start() {
|
|
||||||
Object.keys(requirejs._eak_seen).forEach((key) => {
|
|
||||||
if (/\/pre\-initializers\//.test(key)) {
|
|
||||||
const module = requirejs(key, null, null, true);
|
|
||||||
if (!module) {
|
|
||||||
throw new Error(key + " must export an initializer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const init = module.default;
|
|
||||||
const oldInitialize = init.initialize;
|
|
||||||
init.initialize = () => {
|
|
||||||
oldInitialize.call(this, this.__container__, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.initializer(init);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(requirejs._eak_seen).forEach((key) => {
|
|
||||||
if (/\/initializers\//.test(key)) {
|
|
||||||
const module = requirejs(key, null, null, true);
|
|
||||||
if (!module) {
|
|
||||||
throw new Error(key + " must export an initializer.");
|
|
||||||
}
|
|
||||||
this.initializer(module.default);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -1,219 +0,0 @@
|
||||||
export default {
|
|
||||||
name: "custom-wizard-step",
|
|
||||||
initialize() {
|
|
||||||
if (window.location.pathname.indexOf("/w/") < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CustomWizard = requirejs(
|
|
||||||
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
|
|
||||||
).default;
|
|
||||||
const updateCachedWizard = requirejs(
|
|
||||||
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
|
|
||||||
).updateCachedWizard;
|
|
||||||
const StepModel = requirejs("wizard/models/step").default;
|
|
||||||
const StepComponent = requirejs("wizard/components/wizard-step").default;
|
|
||||||
const ajax = requirejs("wizard/lib/ajax").ajax;
|
|
||||||
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
|
||||||
const discourseComputed = requirejs("discourse-common/utils/decorators")
|
|
||||||
.default;
|
|
||||||
const cook = requirejs(
|
|
||||||
"discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite"
|
|
||||||
).cook;
|
|
||||||
const { schedule } = requirejs("@ember/runloop");
|
|
||||||
const { alias, not } = requirejs("@ember/object/computed");
|
|
||||||
const { translatedText } = requirejs(
|
|
||||||
"discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n"
|
|
||||||
);
|
|
||||||
|
|
||||||
StepModel.reopen({
|
|
||||||
@discourseComputed("wizardId", "id")
|
|
||||||
i18nKey(wizardId, stepId) {
|
|
||||||
return `${wizardId}.${stepId}`;
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("i18nKey", "title")
|
|
||||||
translatedTitle(i18nKey, title) {
|
|
||||||
return translatedText(`${i18nKey}.title`, title);
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("i18nKey", "description")
|
|
||||||
translatedDescription(i18nKey, description) {
|
|
||||||
return translatedText(`${i18nKey}.description`, description);
|
|
||||||
},
|
|
||||||
|
|
||||||
save() {
|
|
||||||
const wizardId = this.get("wizardId");
|
|
||||||
const fields = {};
|
|
||||||
|
|
||||||
this.get("fields").forEach((f) => {
|
|
||||||
if (f.type !== "text_only") {
|
|
||||||
fields[f.id] = f.value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return ajax({
|
|
||||||
url: `/w/${wizardId}/steps/${this.get("id")}`,
|
|
||||||
type: "PUT",
|
|
||||||
data: { fields },
|
|
||||||
}).catch((response) => {
|
|
||||||
if (
|
|
||||||
response &&
|
|
||||||
response.responseJSON &&
|
|
||||||
response.responseJSON.errors
|
|
||||||
) {
|
|
||||||
let wizardErrors = [];
|
|
||||||
response.responseJSON.errors.forEach((err) => {
|
|
||||||
if (err.field === wizardId) {
|
|
||||||
wizardErrors.push(err.description);
|
|
||||||
} else if (err.field) {
|
|
||||||
this.fieldError(err.field, err.description);
|
|
||||||
} else if (err) {
|
|
||||||
wizardErrors.push(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (wizardErrors.length) {
|
|
||||||
this.handleWizardError(wizardErrors.join("\n"));
|
|
||||||
}
|
|
||||||
this.animateInvalidFields();
|
|
||||||
throw response;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response && response.responseText) {
|
|
||||||
const responseText = response.responseText;
|
|
||||||
const start = responseText.indexOf(">") + 1;
|
|
||||||
const end = responseText.indexOf("plugins");
|
|
||||||
const message = responseText.substring(start, end);
|
|
||||||
this.handleWizardError(message);
|
|
||||||
throw message;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
handleWizardError(message) {
|
|
||||||
this.set("message", {
|
|
||||||
state: "error",
|
|
||||||
text: message,
|
|
||||||
});
|
|
||||||
Ember.run.later(() => this.set("message", null), 6000);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
StepComponent.reopen({
|
|
||||||
classNameBindings: ["step.id"],
|
|
||||||
|
|
||||||
autoFocus() {
|
|
||||||
schedule("afterRender", () => {
|
|
||||||
const $invalid = $(
|
|
||||||
".wizard-field.invalid:nth-of-type(1) .wizard-focusable"
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($invalid.length) {
|
|
||||||
return $invalid.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(".wizard-focusable:first").focus();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
animateInvalidFields() {
|
|
||||||
schedule("afterRender", () => {
|
|
||||||
let $element = $(
|
|
||||||
".invalid input[type=text],.invalid textarea,.invalid input[type=checkbox],.invalid .select-kit"
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($element.length) {
|
|
||||||
$([document.documentElement, document.body]).animate(
|
|
||||||
{
|
|
||||||
scrollTop: $element.offset().top - 200,
|
|
||||||
},
|
|
||||||
400,
|
|
||||||
function () {
|
|
||||||
$element.wiggle(2, 100);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
ensureStartsAtTop: function () {
|
|
||||||
window.scrollTo(0, 0);
|
|
||||||
}.observes("step.id"),
|
|
||||||
|
|
||||||
showQuitButton: function () {
|
|
||||||
const index = this.get("step.index");
|
|
||||||
const required = this.get("wizard.required");
|
|
||||||
return index === 0 && !required;
|
|
||||||
}.property("step.index", "wizard.required"),
|
|
||||||
|
|
||||||
@discourseComputed("step.translatedTitle")
|
|
||||||
cookedTitle(title) {
|
|
||||||
return cook(title);
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("step.translatedDescription")
|
|
||||||
cookedDescription(description) {
|
|
||||||
return cook(description);
|
|
||||||
},
|
|
||||||
|
|
||||||
bannerImage: function () {
|
|
||||||
const src = this.get("step.banner");
|
|
||||||
if (!src) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return getUrl(src);
|
|
||||||
}.property("step.banner"),
|
|
||||||
|
|
||||||
@discourseComputed("step.fields.[]")
|
|
||||||
primaryButtonIndex(fields) {
|
|
||||||
return fields.length + 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("step.fields.[]")
|
|
||||||
secondaryButtonIndex(fields) {
|
|
||||||
return fields.length + 2;
|
|
||||||
},
|
|
||||||
|
|
||||||
handleMessage: function () {
|
|
||||||
const message = this.get("step.message");
|
|
||||||
this.sendAction("showMessage", message);
|
|
||||||
}.observes("step.message"),
|
|
||||||
|
|
||||||
showNextButton: not("step.final"),
|
|
||||||
showDoneButton: alias("step.final"),
|
|
||||||
|
|
||||||
advance() {
|
|
||||||
this.set("saving", true);
|
|
||||||
this.get("step")
|
|
||||||
.save()
|
|
||||||
.then((response) => {
|
|
||||||
updateCachedWizard(CustomWizard.build(response["wizard"]));
|
|
||||||
|
|
||||||
if (response["final"]) {
|
|
||||||
CustomWizard.finished(response);
|
|
||||||
} else {
|
|
||||||
this.sendAction("goNext", response);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => this.animateInvalidFields())
|
|
||||||
.finally(() => this.set("saving", false));
|
|
||||||
},
|
|
||||||
|
|
||||||
keyPress() {},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
quit() {
|
|
||||||
this.get("wizard").skip();
|
|
||||||
},
|
|
||||||
|
|
||||||
done() {
|
|
||||||
this.send("nextStep");
|
|
||||||
},
|
|
||||||
|
|
||||||
showMessage(message) {
|
|
||||||
this.sendAction("showMessage", message);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,126 +0,0 @@
|
||||||
export default {
|
|
||||||
name: "custom-routes",
|
|
||||||
initialize(app) {
|
|
||||||
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 getUrl = requirejs("discourse-common/lib/get-url").default;
|
|
||||||
const Store = requirejs("discourse/services/store").default;
|
|
||||||
const registerRawHelpers = requirejs(
|
|
||||||
"discourse-common/lib/raw-handlebars-helpers"
|
|
||||||
).registerRawHelpers;
|
|
||||||
const createHelperContext = requirejs("discourse-common/lib/helpers")
|
|
||||||
.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;
|
|
||||||
const RestAdapter = requirejs("discourse/adapters/rest").default;
|
|
||||||
const Session = requirejs("discourse/models/session").default;
|
|
||||||
const setDefaultOwner = requirejs("discourse-common/lib/get-owner")
|
|
||||||
.setDefaultOwner;
|
|
||||||
const messageBus = requirejs("message-bus-client").default;
|
|
||||||
const getToken = requirejs("wizard/lib/ajax").getToken;
|
|
||||||
const setEnvironment = requirejs("discourse-common/config/environment")
|
|
||||||
.setEnvironment;
|
|
||||||
const container = app.__container__;
|
|
||||||
Discourse.Model = EmberObject.extend();
|
|
||||||
Discourse.__container__ = container;
|
|
||||||
setDefaultOwner(container);
|
|
||||||
registerRawHelpers(RawHandlebars, Handlebars);
|
|
||||||
|
|
||||||
// IE11 Polyfill - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Polyfill
|
|
||||||
if (!Object.entries) {
|
|
||||||
Object.entries = function (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]]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return resArray;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(Ember.TEMPLATES).forEach((k) => {
|
|
||||||
if (k.indexOf("select-kit") === 0) {
|
|
||||||
let template = Ember.TEMPLATES[k];
|
|
||||||
define(k, () => template);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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 });
|
|
||||||
targets.forEach((t) => app.inject(t, "siteSettings", "site-settings:main"));
|
|
||||||
|
|
||||||
app.register("message-bus:main", messageBus, { instantiate: false });
|
|
||||||
targets.forEach((t) => app.inject(t, "messageBus", "message-bus:main"));
|
|
||||||
|
|
||||||
app.register("service:store", Store);
|
|
||||||
targets.forEach((t) => app.inject(t, "store", "service:store"));
|
|
||||||
targets.forEach((t) => app.inject(t, "appEvents", "service:app-events"));
|
|
||||||
|
|
||||||
app.register("adapter:rest", RestAdapter);
|
|
||||||
|
|
||||||
const site = Site.current();
|
|
||||||
app.register("site:main", site, { instantiate: false });
|
|
||||||
targets.forEach((t) => app.inject(t, "site", "site:main"));
|
|
||||||
|
|
||||||
site.set("can_create_tag", false);
|
|
||||||
app.register("session:main", Session.current(), { instantiate: false });
|
|
||||||
targets.forEach((t) => app.inject(t, "session", "session:main"));
|
|
||||||
|
|
||||||
createHelperContext({
|
|
||||||
siteSettings: container.lookup("site-settings:main"),
|
|
||||||
currentUser: container.lookup("current-user:main"),
|
|
||||||
site: container.lookup("site:main"),
|
|
||||||
session: container.lookup("session:main"),
|
|
||||||
capabilities: container.lookup("capabilities:main"),
|
|
||||||
});
|
|
||||||
|
|
||||||
const session = container.lookup("session:main");
|
|
||||||
const setupData = document.getElementById("data-discourse-setup").dataset;
|
|
||||||
session.set("highlightJsPath", setupData.highlightJsPath);
|
|
||||||
setEnvironment(setupData.environment);
|
|
||||||
|
|
||||||
Router.reopen({
|
|
||||||
rootURL: getUrl("/w/"),
|
|
||||||
});
|
|
||||||
|
|
||||||
Router.map(function () {
|
|
||||||
this.route("custom", { path: "/:wizard_id" }, function () {
|
|
||||||
this.route("steps");
|
|
||||||
this.route("step", { path: "/steps/:step_id" });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ApplicationRoute.reopen({
|
|
||||||
redirect() {
|
|
||||||
this.transitionTo("custom");
|
|
||||||
},
|
|
||||||
model() {},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add a CSRF token to all AJAX requests
|
|
||||||
let token = getToken();
|
|
||||||
session.set("csrfToken", token);
|
|
||||||
let callbacks = $.Callbacks();
|
|
||||||
$.ajaxPrefilter(callbacks.fire);
|
|
||||||
|
|
||||||
callbacks.add(function (options, originalOptions, xhr) {
|
|
||||||
if (!options.crossDomain) {
|
|
||||||
xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
12
assets/javascripts/wizard/lib/initialize/create-contexts.js.es6
Normale Datei
12
assets/javascripts/wizard/lib/initialize/create-contexts.js.es6
Normale Datei
|
@ -0,0 +1,12 @@
|
||||||
|
export default {
|
||||||
|
run(app, container) {
|
||||||
|
const { createHelperContext } = requirejs("discourse-common/lib/helpers");
|
||||||
|
|
||||||
|
createHelperContext({
|
||||||
|
siteSettings: container.lookup('site-settings:main'),
|
||||||
|
site: container.lookup("site:main"),
|
||||||
|
session: container.lookup("session:main"),
|
||||||
|
capabilities: container.lookup("capabilities:main"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
49
assets/javascripts/wizard/lib/initialize/inject-objects.js.es6
Normale Datei
49
assets/javascripts/wizard/lib/initialize/inject-objects.js.es6
Normale Datei
|
@ -0,0 +1,49 @@
|
||||||
|
export default {
|
||||||
|
run(app, container) {
|
||||||
|
const Store = requirejs("discourse/services/store").default;
|
||||||
|
const Site = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/models/site"
|
||||||
|
).default;
|
||||||
|
const Session = requirejs("discourse/models/session").default;
|
||||||
|
const RestAdapter = requirejs("discourse/adapters/rest").default;
|
||||||
|
const messageBus = requirejs("message-bus-client").default;
|
||||||
|
const sniffCapabilites = requirejs("discourse/pre-initializers/sniff-capabilities").default;
|
||||||
|
const site = Site.current();
|
||||||
|
const session = Session.current();
|
||||||
|
|
||||||
|
const registrations = [
|
||||||
|
["site-settings:main", app.SiteSettings, false],
|
||||||
|
["message-bus:main", messageBus, false],
|
||||||
|
["site:main", site, false],
|
||||||
|
["session:main", session, false],
|
||||||
|
["service:store", Store, true],
|
||||||
|
["adapter:rest", RestAdapter, true]
|
||||||
|
];
|
||||||
|
|
||||||
|
registrations.forEach(registration => {
|
||||||
|
if (!app.hasRegistration(registration[0])) {
|
||||||
|
app.register(registration[0], registration[1], { instantiate: registration[2] });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const targets = ["controller", "component", "route", "model", "adapter", "mixin"];
|
||||||
|
const injections = [
|
||||||
|
["siteSettings", "site-settings:main"],
|
||||||
|
["messageBus", "message-bus:main"],
|
||||||
|
["site", "site:main"],
|
||||||
|
["session", "session:main"],
|
||||||
|
["store", "service:store"],
|
||||||
|
["appEvents", "service:app-events"]
|
||||||
|
];
|
||||||
|
|
||||||
|
injections.forEach(injection => {
|
||||||
|
targets.forEach((t) => app.inject(t, injection[0], injection[1]));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!app.hasRegistration("capabilities:main")) {
|
||||||
|
sniffCapabilites.initialize(null, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
site.set("can_create_tag", false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,117 +1,25 @@
|
||||||
import { dasherize } from "@ember/string";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "custom-wizard-field",
|
run(app, container) {
|
||||||
initialize() {
|
const getToken = requirejs("wizard/lib/ajax").getToken;
|
||||||
if (window.location.pathname.indexOf("/w/") < 0) {
|
const isTesting = requirejs("discourse-common/config/environment").isTesting;
|
||||||
return;
|
|
||||||
|
if (!isTesting) {
|
||||||
|
// Add a CSRF token to all AJAX requests
|
||||||
|
let token = getToken();
|
||||||
|
session.set("csrfToken", token);
|
||||||
|
let callbacks = $.Callbacks();
|
||||||
|
$.ajaxPrefilter(callbacks.fire);
|
||||||
|
|
||||||
|
callbacks.add(function (options, originalOptions, xhr) {
|
||||||
|
if (!options.crossDomain) {
|
||||||
|
xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken"));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const FieldComponent = requirejs("wizard/components/wizard-field").default;
|
|
||||||
const FieldModel = requirejs("wizard/models/wizard-field").default;
|
|
||||||
const { cook } = requirejs(
|
|
||||||
"discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite"
|
|
||||||
);
|
|
||||||
const DEditor = requirejs("discourse/components/d-editor").default;
|
const DEditor = requirejs("discourse/components/d-editor").default;
|
||||||
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
const { clipboardHelpers } = requirejs("discourse/lib/utilities");
|
||||||
const toMarkdown = requirejs("discourse/lib/to-markdown").default;
|
const toMarkdown = requirejs("discourse/lib/to-markdown").default;
|
||||||
const { translatedText } = requirejs(
|
|
||||||
"discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n"
|
|
||||||
);
|
|
||||||
|
|
||||||
FieldComponent.reopen({
|
|
||||||
classNameBindings: ["field.id"],
|
|
||||||
|
|
||||||
@discourseComputed("field.translatedDescription")
|
|
||||||
cookedDescription(description) {
|
|
||||||
return cook(description);
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("field.type")
|
|
||||||
textType(fieldType) {
|
|
||||||
return ["text", "textarea"].includes(fieldType);
|
|
||||||
},
|
|
||||||
|
|
||||||
inputComponentName: function () {
|
|
||||||
const type = this.get("field.type");
|
|
||||||
const id = this.get("field.id");
|
|
||||||
if (["text_only"].includes(type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return dasherize(type === "component" ? id : `wizard-field-${type}`);
|
|
||||||
}.property("field.type", "field.id"),
|
|
||||||
});
|
|
||||||
|
|
||||||
const StandardFieldValidation = [
|
|
||||||
"text",
|
|
||||||
"number",
|
|
||||||
"textarea",
|
|
||||||
"dropdown",
|
|
||||||
"tag",
|
|
||||||
"image",
|
|
||||||
"user_selector",
|
|
||||||
"text_only",
|
|
||||||
"composer",
|
|
||||||
"category",
|
|
||||||
"group",
|
|
||||||
"date",
|
|
||||||
"time",
|
|
||||||
"date_time",
|
|
||||||
];
|
|
||||||
|
|
||||||
FieldModel.reopen({
|
|
||||||
@discourseComputed("wizardId", "stepId", "id")
|
|
||||||
i18nKey(wizardId, stepId, id) {
|
|
||||||
return `${wizardId}.${stepId}.${id}`;
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("i18nKey", "label")
|
|
||||||
translatedLabel(i18nKey, label) {
|
|
||||||
return translatedText(`${i18nKey}.label`, label);
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("i18nKey", "placeholder")
|
|
||||||
translatedPlaceholder(i18nKey, placeholder) {
|
|
||||||
return translatedText(`${i18nKey}.placeholder`, placeholder);
|
|
||||||
},
|
|
||||||
|
|
||||||
@discourseComputed("i18nKey", "description")
|
|
||||||
translatedDescription(i18nKey, description) {
|
|
||||||
return translatedText(`${i18nKey}.description`, description);
|
|
||||||
},
|
|
||||||
|
|
||||||
check() {
|
|
||||||
if (this.customCheck) {
|
|
||||||
return this.customCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
let valid = this.valid;
|
|
||||||
|
|
||||||
if (!this.required) {
|
|
||||||
this.setValid(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const val = this.get("value");
|
|
||||||
const type = this.get("type");
|
|
||||||
|
|
||||||
if (type === "checkbox") {
|
|
||||||
valid = val;
|
|
||||||
} else if (type === "upload") {
|
|
||||||
valid = val && val.id > 0;
|
|
||||||
} else if (StandardFieldValidation.indexOf(type) > -1) {
|
|
||||||
valid = val && val.toString().length > 0;
|
|
||||||
} else if (type === "url") {
|
|
||||||
valid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setValid(valid);
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const isInside = (text, regex) => {
|
const isInside = (text, regex) => {
|
||||||
const matches = text.match(regex);
|
const matches = text.match(regex);
|
||||||
return matches && matches.length % 2;
|
return matches && matches.length % 2;
|
||||||
|
@ -218,5 +126,19 @@ 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) {
|
||||||
|
let ownProps = Object.keys(obj),
|
||||||
|
i = ownProps.length,
|
||||||
|
resArray = new Array(i); // preallocate the Array
|
||||||
|
while (i--) {
|
||||||
|
resArray[i] = [ownProps[i], obj[ownProps[i]]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return resArray;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
26
assets/javascripts/wizard/lib/initialize/register-files.js.es6
Normale Datei
26
assets/javascripts/wizard/lib/initialize/register-files.js.es6
Normale Datei
|
@ -0,0 +1,26 @@
|
||||||
|
export default {
|
||||||
|
run(app, container) {
|
||||||
|
const RawHandlebars = requirejs("discourse-common/lib/raw-handlebars").default;
|
||||||
|
const Handlebars = requirejs("handlebars").default;
|
||||||
|
const registerRawHelpers = requirejs("discourse-common/lib/raw-handlebars-helpers").registerRawHelpers;
|
||||||
|
const { registerHelpers } = requirejs("discourse-common/lib/helpers");
|
||||||
|
const jqueryPlugins = requirejs("discourse/initializers/jquery-plugins").default;
|
||||||
|
|
||||||
|
Object.keys(Ember.TEMPLATES).forEach((k) => {
|
||||||
|
if (k.indexOf("select-kit") === 0) {
|
||||||
|
let template = Ember.TEMPLATES[k];
|
||||||
|
define(k, () => template);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(requirejs.entries).forEach((entry) => {
|
||||||
|
if (/\/helpers\//.test(entry)) {
|
||||||
|
requirejs(entry, null, null, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
registerRawHelpers(RawHandlebars, Handlebars);
|
||||||
|
registerHelpers(app);
|
||||||
|
jqueryPlugins.initialize(container, app);
|
||||||
|
}
|
||||||
|
}
|
49
assets/javascripts/wizard/lib/initialize/wizard.js.es6
Normale Datei
49
assets/javascripts/wizard/lib/initialize/wizard.js.es6
Normale Datei
|
@ -0,0 +1,49 @@
|
||||||
|
export default {
|
||||||
|
name: "custom-wizard",
|
||||||
|
initialize(app) {
|
||||||
|
const isTesting = requirejs("discourse-common/config/environment").isTesting;
|
||||||
|
const isWizard = window.location.pathname.indexOf("/w/") > -1;
|
||||||
|
|
||||||
|
if (!isWizard && !isTesting()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const container = app.__container__;
|
||||||
|
const setDefaultOwner = requirejs("discourse-common/lib/get-owner").setDefaultOwner;
|
||||||
|
setDefaultOwner(container);
|
||||||
|
|
||||||
|
if (!isTesting()) {
|
||||||
|
const PreloadStore = requirejs("discourse/lib/preload-store").default;
|
||||||
|
|
||||||
|
let preloaded;
|
||||||
|
const preloadedDataElement = document.getElementById("data-preloaded-wizard");
|
||||||
|
if (preloadedDataElement) {
|
||||||
|
preloaded = JSON.parse(preloadedDataElement.dataset.preloadedWizard);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(preloaded).forEach(function (key) {
|
||||||
|
PreloadStore.store(key, JSON.parse(preloaded[key]));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.SiteSettings = PreloadStore.get("siteSettings");
|
||||||
|
}
|
||||||
|
|
||||||
|
const setEnvironment = requirejs("discourse-common/config/environment").setEnvironment;
|
||||||
|
const setupData = document.getElementById("data-discourse-setup").dataset;
|
||||||
|
setEnvironment(setupData.environment);
|
||||||
|
|
||||||
|
const Session = requirejs("discourse/models/session").default;
|
||||||
|
const session = Session.current();
|
||||||
|
session.set("highlightJsPath", setupData.highlightJsPath);
|
||||||
|
|
||||||
|
[
|
||||||
|
'register-files',
|
||||||
|
'inject-objects',
|
||||||
|
'create-contexts',
|
||||||
|
'patch-components'
|
||||||
|
].forEach(fileName => {
|
||||||
|
const initializer = requirejs(`discourse/plugins/discourse-custom-wizard/wizard/lib/initialize/${fileName}`).default;
|
||||||
|
initializer.run(app, container);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,71 +0,0 @@
|
||||||
// lite version of discourse/lib/utilities
|
|
||||||
|
|
||||||
export function determinePostReplaceSelection({
|
|
||||||
selection,
|
|
||||||
needle,
|
|
||||||
replacement,
|
|
||||||
}) {
|
|
||||||
const diff =
|
|
||||||
replacement.end - replacement.start - (needle.end - needle.start);
|
|
||||||
|
|
||||||
if (selection.end <= needle.start) {
|
|
||||||
// Selection ends (and starts) before needle.
|
|
||||||
return { start: selection.start, end: selection.end };
|
|
||||||
} else if (selection.start <= needle.start) {
|
|
||||||
// Selection starts before needle...
|
|
||||||
if (selection.end < needle.end) {
|
|
||||||
// ... and ends inside needle.
|
|
||||||
return { start: selection.start, end: needle.start };
|
|
||||||
} else {
|
|
||||||
// ... and spans needle completely.
|
|
||||||
return { start: selection.start, end: selection.end + diff };
|
|
||||||
}
|
|
||||||
} else if (selection.start < needle.end) {
|
|
||||||
// Selection starts inside needle...
|
|
||||||
if (selection.end <= needle.end) {
|
|
||||||
// ... and ends inside needle.
|
|
||||||
return { start: replacement.end, end: replacement.end };
|
|
||||||
} else {
|
|
||||||
// ... and spans end of needle.
|
|
||||||
return { start: replacement.end, end: selection.end + diff };
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Selection starts (and ends) behind needle.
|
|
||||||
return { start: selection.start + diff, end: selection.end + diff };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const toArray = (items) => {
|
|
||||||
items = items || [];
|
|
||||||
|
|
||||||
if (!Array.isArray(items)) {
|
|
||||||
return Array.from(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function clipboardData(e, canUpload) {
|
|
||||||
const clipboard =
|
|
||||||
e.clipboardData ||
|
|
||||||
e.originalEvent.clipboardData ||
|
|
||||||
e.delegatedEvent.originalEvent.clipboardData;
|
|
||||||
|
|
||||||
const types = toArray(clipboard.types);
|
|
||||||
let files = toArray(clipboard.files);
|
|
||||||
|
|
||||||
if (types.includes("Files") && files.length === 0) {
|
|
||||||
// for IE
|
|
||||||
files = toArray(clipboard.items).filter((i) => i.kind === "file");
|
|
||||||
}
|
|
||||||
|
|
||||||
canUpload = files && canUpload && !types.includes("text/plain");
|
|
||||||
const canUploadImage =
|
|
||||||
canUpload && files.filter((f) => f.type.match("^image/"))[0];
|
|
||||||
const canPasteHtml =
|
|
||||||
Discourse.SiteSettings.enable_rich_text_paste &&
|
|
||||||
types.includes("text/html") &&
|
|
||||||
!canUploadImage;
|
|
||||||
|
|
||||||
return { clipboard, types, canUpload, canPasteHtml };
|
|
||||||
}
|
|
79
assets/javascripts/wizard/models/field.js.es6
Normale Datei
79
assets/javascripts/wizard/models/field.js.es6
Normale Datei
|
@ -0,0 +1,79 @@
|
||||||
|
import EmberObject from "@ember/object";
|
||||||
|
import ValidState from "wizard/mixins/valid-state";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import { translatedText } from "discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n";
|
||||||
|
|
||||||
|
const StandardFieldValidation = [
|
||||||
|
"text",
|
||||||
|
"number",
|
||||||
|
"textarea",
|
||||||
|
"dropdown",
|
||||||
|
"tag",
|
||||||
|
"image",
|
||||||
|
"user_selector",
|
||||||
|
"text_only",
|
||||||
|
"composer",
|
||||||
|
"category",
|
||||||
|
"group",
|
||||||
|
"date",
|
||||||
|
"time",
|
||||||
|
"date_time",
|
||||||
|
];
|
||||||
|
|
||||||
|
export default EmberObject.extend(ValidState, {
|
||||||
|
id: null,
|
||||||
|
type: null,
|
||||||
|
value: null,
|
||||||
|
required: null,
|
||||||
|
warning: null,
|
||||||
|
|
||||||
|
@discourseComputed("wizardId", "stepId", "id")
|
||||||
|
i18nKey(wizardId, stepId, id) {
|
||||||
|
return `${wizardId}.${stepId}.${id}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("i18nKey", "label")
|
||||||
|
translatedLabel(i18nKey, label) {
|
||||||
|
return translatedText(`${i18nKey}.label`, label);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("i18nKey", "placeholder")
|
||||||
|
translatedPlaceholder(i18nKey, placeholder) {
|
||||||
|
return translatedText(`${i18nKey}.placeholder`, placeholder);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("i18nKey", "description")
|
||||||
|
translatedDescription(i18nKey, description) {
|
||||||
|
return translatedText(`${i18nKey}.description`, description);
|
||||||
|
},
|
||||||
|
|
||||||
|
check() {
|
||||||
|
if (this.customCheck) {
|
||||||
|
return this.customCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
let valid = this.valid;
|
||||||
|
|
||||||
|
if (!this.required) {
|
||||||
|
this.setValid(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const val = this.get("value");
|
||||||
|
const type = this.get("type");
|
||||||
|
|
||||||
|
if (type === "checkbox") {
|
||||||
|
valid = val;
|
||||||
|
} else if (type === "upload") {
|
||||||
|
valid = val && val.id > 0;
|
||||||
|
} else if (StandardFieldValidation.indexOf(type) > -1) {
|
||||||
|
valid = val && val.toString().length > 0;
|
||||||
|
} else if (type === "url") {
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setValid(valid);
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,10 +1,11 @@
|
||||||
import Site from "discourse/models/site";
|
import Site from "discourse/models/site";
|
||||||
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
|
|
||||||
export default Site.reopenClass({
|
export default Site.reopenClass({
|
||||||
// There is no site data actually loaded by the CW yet. This placeholder is
|
// There is no site data actually loaded by the CW yet. This placeholder is
|
||||||
// needed by imported classes
|
// needed by imported classes
|
||||||
createCurrent() {
|
createCurrent() {
|
||||||
const store = Discourse.__container__.lookup("service:store");
|
const store = getOwner(this).lookup("service:store");
|
||||||
return store.createRecord("site", {});
|
return store.createRecord("site", {});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
114
assets/javascripts/wizard/models/step.js.es6
Normale Datei
114
assets/javascripts/wizard/models/step.js.es6
Normale Datei
|
@ -0,0 +1,114 @@
|
||||||
|
import EmberObject from "@ember/object";
|
||||||
|
import ValidState from "wizard/mixins/valid-state";
|
||||||
|
import { ajax } from "wizard/lib/ajax";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import { translatedText } from "discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n";
|
||||||
|
|
||||||
|
export default EmberObject.extend(ValidState, {
|
||||||
|
id: null,
|
||||||
|
|
||||||
|
@discourseComputed("wizardId", "id")
|
||||||
|
i18nKey(wizardId, stepId) {
|
||||||
|
return `${wizardId}.${stepId}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("i18nKey", "title")
|
||||||
|
translatedTitle(i18nKey, title) {
|
||||||
|
return translatedText(`${i18nKey}.title`, title);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("i18nKey", "description")
|
||||||
|
translatedDescription(i18nKey, description) {
|
||||||
|
return translatedText(`${i18nKey}.description`, description);
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("index")
|
||||||
|
displayIndex: (index) => index + 1,
|
||||||
|
|
||||||
|
@discourseComputed("fields.[]")
|
||||||
|
fieldsById(fields) {
|
||||||
|
const lookup = {};
|
||||||
|
fields.forEach((field) => (lookup[field.get("id")] = field));
|
||||||
|
return lookup;
|
||||||
|
},
|
||||||
|
|
||||||
|
validate() {
|
||||||
|
let allValid = true;
|
||||||
|
const result = { warnings: [] };
|
||||||
|
|
||||||
|
this.fields.forEach((field) => {
|
||||||
|
allValid = allValid && field.check();
|
||||||
|
const warning = field.get("warning");
|
||||||
|
if (warning) {
|
||||||
|
result.warnings.push(warning);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setValid(allValid);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
fieldError(id, description) {
|
||||||
|
const field = this.fields.findBy("id", id);
|
||||||
|
if (field) {
|
||||||
|
field.setValid(false, description);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
save() {
|
||||||
|
const wizardId = this.get("wizardId");
|
||||||
|
const fields = {};
|
||||||
|
|
||||||
|
this.get("fields").forEach((f) => {
|
||||||
|
if (f.type !== "text_only") {
|
||||||
|
fields[f.id] = f.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return ajax({
|
||||||
|
url: `/w/${wizardId}/steps/${this.get("id")}`,
|
||||||
|
type: "PUT",
|
||||||
|
data: { fields },
|
||||||
|
}).catch((response) => {
|
||||||
|
if (
|
||||||
|
response &&
|
||||||
|
response.responseJSON &&
|
||||||
|
response.responseJSON.errors
|
||||||
|
) {
|
||||||
|
let wizardErrors = [];
|
||||||
|
response.responseJSON.errors.forEach((err) => {
|
||||||
|
if (err.field === wizardId) {
|
||||||
|
wizardErrors.push(err.description);
|
||||||
|
} else if (err.field) {
|
||||||
|
this.fieldError(err.field, err.description);
|
||||||
|
} else if (err) {
|
||||||
|
wizardErrors.push(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (wizardErrors.length) {
|
||||||
|
this.handleWizardError(wizardErrors.join("\n"));
|
||||||
|
}
|
||||||
|
this.animateInvalidFields();
|
||||||
|
throw response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response && response.responseText) {
|
||||||
|
const responseText = response.responseText;
|
||||||
|
const start = responseText.indexOf(">") + 1;
|
||||||
|
const end = responseText.indexOf("plugins");
|
||||||
|
const message = responseText.substring(start, end);
|
||||||
|
this.handleWizardError(message);
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleWizardError(message) {
|
||||||
|
this.set("message", {
|
||||||
|
state: "error",
|
||||||
|
text: message,
|
||||||
|
});
|
||||||
|
Ember.run.later(() => this.set("message", null), 6000);
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,9 +1,9 @@
|
||||||
import { default as computed } from "discourse-common/utils/decorators";
|
import { default as computed } from "discourse-common/utils/decorators";
|
||||||
import getUrl from "discourse-common/lib/get-url";
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
import WizardField from "wizard/models/wizard-field";
|
import Field from "./field";
|
||||||
import { ajax } from "wizard/lib/ajax";
|
import { ajax } from "wizard/lib/ajax";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import Step from "wizard/models/step";
|
import Step from "./step";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import Site from "./site";
|
import Site from "./site";
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ CustomWizard.reopenClass({
|
||||||
stepObj.fields = stepObj.fields.map((f) => {
|
stepObj.fields = stepObj.fields.map((f) => {
|
||||||
f.wizardId = wizardJson.id;
|
f.wizardId = wizardJson.id;
|
||||||
f.stepId = stepObj.id;
|
f.stepId = stepObj.id;
|
||||||
return WizardField.create(f);
|
return Field.create(f);
|
||||||
});
|
});
|
||||||
|
|
||||||
return stepObj;
|
return stepObj;
|
17
assets/javascripts/wizard/router.js.es6
Normale Datei
17
assets/javascripts/wizard/router.js.es6
Normale Datei
|
@ -0,0 +1,17 @@
|
||||||
|
import EmberRouter from "@ember/routing/router";
|
||||||
|
import getUrl from "discourse-common/lib/get-url";
|
||||||
|
import { isTesting } from "discourse-common/config/environment";
|
||||||
|
|
||||||
|
const Router = EmberRouter.extend({
|
||||||
|
rootURL: isTesting() ? getUrl("/") : getUrl("/w/"),
|
||||||
|
location: isTesting() ? "none" : "history",
|
||||||
|
});
|
||||||
|
|
||||||
|
Router.map(function () {
|
||||||
|
this.route("wizard", { path: "/:wizard_id" }, function () {
|
||||||
|
this.route("steps", { path: "/steps", resetNamespace: true });
|
||||||
|
this.route("step", { path: "/steps/:step_id", resetNamespace: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Router;
|
3
assets/javascripts/wizard/routes/application.js.es6
Normale Datei
3
assets/javascripts/wizard/routes/application.js.es6
Normale Datei
|
@ -0,0 +1,3 @@
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
|
|
||||||
|
export default Route.extend();
|
|
@ -1,5 +0,0 @@
|
||||||
export default Ember.Route.extend({
|
|
||||||
redirect() {
|
|
||||||
this.transitionTo("custom.index");
|
|
||||||
},
|
|
||||||
});
|
|
9
assets/javascripts/wizard/routes/index.js.es6
Normale Datei
9
assets/javascripts/wizard/routes/index.js.es6
Normale Datei
|
@ -0,0 +1,9 @@
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
|
|
||||||
|
export default Route.extend({
|
||||||
|
beforeModel(transition) {
|
||||||
|
if (transition.intent.params) {
|
||||||
|
this.transitionTo("wizard");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,7 +1,8 @@
|
||||||
import WizardI18n from "../lib/wizard-i18n";
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
import { getCachedWizard } from "../models/custom";
|
import { getCachedWizard } from "../models/wizard";
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Route.extend({
|
||||||
beforeModel() {
|
beforeModel() {
|
||||||
this.set("wizard", getCachedWizard());
|
this.set("wizard", getCachedWizard());
|
||||||
},
|
},
|
||||||
|
@ -19,11 +20,15 @@ export default Ember.Route.extend({
|
||||||
|
|
||||||
afterModel(model) {
|
afterModel(model) {
|
||||||
if (model.completed) {
|
if (model.completed) {
|
||||||
return this.transitionTo("index");
|
return this.transitionTo("wizard.index");
|
||||||
}
|
}
|
||||||
return model.set("wizardId", this.wizard.id);
|
return model.set("wizardId", this.wizard.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderTemplate() {
|
||||||
|
this.render('wizard/templates/step');
|
||||||
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
let props = {
|
let props = {
|
||||||
step: model,
|
step: model,
|
7
assets/javascripts/wizard/routes/steps.js.es6
Normale Datei
7
assets/javascripts/wizard/routes/steps.js.es6
Normale Datei
|
@ -0,0 +1,7 @@
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
|
|
||||||
|
export default Route.extend({
|
||||||
|
redirect() {
|
||||||
|
this.transitionTo("wizard.index");
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,10 +1,11 @@
|
||||||
import { getCachedWizard } from "../models/custom";
|
import { getCachedWizard } from "../models/wizard";
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Route.extend({
|
||||||
beforeModel() {
|
beforeModel() {
|
||||||
const wizard = getCachedWizard();
|
const wizard = getCachedWizard();
|
||||||
if (wizard && wizard.permitted && !wizard.completed && wizard.start) {
|
if (wizard && wizard.user && wizard.permitted && !wizard.completed && wizard.start) {
|
||||||
this.replaceWith("custom.step", wizard.start);
|
this.replaceWith("step", wizard.start);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -12,6 +13,10 @@ export default Ember.Route.extend({
|
||||||
return getCachedWizard();
|
return getCachedWizard();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderTemplate() {
|
||||||
|
this.render('wizard/templates/wizard-index');
|
||||||
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
if (model && model.id) {
|
if (model && model.id) {
|
||||||
const completed = model.get("completed");
|
const completed = model.get("completed");
|
||||||
|
@ -19,17 +24,20 @@ export default Ember.Route.extend({
|
||||||
const wizardId = model.get("id");
|
const wizardId = model.get("id");
|
||||||
const user = model.get("user");
|
const user = model.get("user");
|
||||||
const name = model.get("name");
|
const name = model.get("name");
|
||||||
|
const requiresLogin = !user;
|
||||||
|
const notPermitted = !permitted;
|
||||||
|
|
||||||
controller.setProperties({
|
const props = {
|
||||||
requiresLogin: !user,
|
requiresLogin,
|
||||||
user,
|
user,
|
||||||
name,
|
name,
|
||||||
completed,
|
completed,
|
||||||
notPermitted: !permitted,
|
notPermitted,
|
||||||
wizardId,
|
wizardId,
|
||||||
});
|
};
|
||||||
|
controller.setProperties(props);
|
||||||
} else {
|
} else {
|
||||||
controller.set("noWizard", true);
|
controller.set("noWizard", true);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
|
@ -1,37 +1,26 @@
|
||||||
/* eslint no-undef: 0*/
|
import { findCustomWizard, updateCachedWizard } from "../models/wizard";
|
||||||
|
|
||||||
import { findCustomWizard, updateCachedWizard } from "../models/custom";
|
|
||||||
import { ajax } from "wizard/lib/ajax";
|
import { ajax } from "wizard/lib/ajax";
|
||||||
import WizardI18n from "../lib/wizard-i18n";
|
import WizardI18n from "../lib/wizard-i18n";
|
||||||
|
import Route from "@ember/routing/route";
|
||||||
|
import { scheduleOnce } from "@ember/runloop";
|
||||||
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Route.extend({
|
||||||
beforeModel(transition) {
|
beforeModel(transition) {
|
||||||
|
if (transition.intent.queryParams) {
|
||||||
this.set("queryParams", transition.intent.queryParams);
|
this.set("queryParams", transition.intent.queryParams);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
model(params) {
|
model(params) {
|
||||||
return findCustomWizard(params.wizard_id, this.get("queryParams"));
|
return findCustomWizard(params.wizard_id, this.get("queryParams"));
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTemplate() {
|
|
||||||
this.render("custom");
|
|
||||||
const wizardModel = this.modelFor("custom");
|
|
||||||
const stepModel = this.modelFor("custom.step");
|
|
||||||
|
|
||||||
if (
|
|
||||||
wizardModel.resume_on_revisit &&
|
|
||||||
wizardModel.submission_last_updated_at &&
|
|
||||||
stepModel.index > 0
|
|
||||||
) {
|
|
||||||
this.showDialog(wizardModel);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
showDialog(wizardModel) {
|
showDialog(wizardModel) {
|
||||||
const title = WizardI18n("wizard.incomplete_submission.title", {
|
const title = WizardI18n("wizard.incomplete_submission.title", {
|
||||||
date: moment(wizardModel.submission_last_updated_at).format(
|
date: moment(wizardModel.submission_last_updated_at).format(
|
||||||
"MMMM Do YYYY"
|
"MMMM Do YYYY"
|
||||||
),
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
|
@ -57,28 +46,36 @@ export default Ember.Route.extend({
|
||||||
|
|
||||||
afterModel(model) {
|
afterModel(model) {
|
||||||
updateCachedWizard(model);
|
updateCachedWizard(model);
|
||||||
|
},
|
||||||
|
|
||||||
return ajax({
|
renderTemplate() {
|
||||||
url: `/site/settings`,
|
this.render('wizard/templates/wizard');
|
||||||
type: "GET",
|
|
||||||
}).then((result) => {
|
|
||||||
$.extend(Wizard.SiteSettings, result);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
const background = model ? model.get("background") : "AliceBlue";
|
const background = model ? model.get("background") : "";
|
||||||
Ember.run.scheduleOnce("afterRender", this, function () {
|
|
||||||
$("body.custom-wizard").css("background", background);
|
scheduleOnce("afterRender", this, function () {
|
||||||
|
$("body").css("background", background);
|
||||||
|
|
||||||
if (model && model.id) {
|
if (model && model.id) {
|
||||||
$("#custom-wizard-main").addClass(model.id.dasherize());
|
$(getOwner(this).rootElement).addClass(model.id.dasherize());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
customWizard: true,
|
customWizard: true,
|
||||||
logoUrl: Wizard.SiteSettings.logo_small,
|
logoUrl: this.siteSettings.logo_small,
|
||||||
reset: null,
|
reset: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stepModel = this.modelFor("step");
|
||||||
|
if (
|
||||||
|
model.resume_on_revisit &&
|
||||||
|
model.submission_last_updated_at &&
|
||||||
|
stepModel.index > 0
|
||||||
|
) {
|
||||||
|
this.showDialog(model);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
|
@ -3,6 +3,7 @@
|
||||||
value=field.value
|
value=field.value
|
||||||
content=field.content
|
content=field.content
|
||||||
tabindex=field.tabindex
|
tabindex=field.tabindex
|
||||||
|
onChange=(action "onChangeValue")
|
||||||
options=(hash
|
options=(hash
|
||||||
none="select_kit.default_header_text"
|
none="select_kit.default_header_text"
|
||||||
)}}
|
)}}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
{{#if noWizard}}
|
|
||||||
{{wizard-no-access text=(wizard-i18n "wizard.none") wizardId=wizardId}}
|
|
||||||
{{else}}
|
|
||||||
{{#if requiresLogin}}
|
|
||||||
{{wizard-no-access text=(wizard-i18n "wizard.requires_login") wizardId=wizardId}}
|
|
||||||
{{else}}
|
|
||||||
{{#if notPermitted}}
|
|
||||||
{{wizard-no-access text=(wizard-i18n "wizard.not_permitted") wizardId=wizardId}}
|
|
||||||
{{else}}
|
|
||||||
{{#if completed}}
|
|
||||||
{{wizard-no-access text=(wizard-i18n "wizard.completed") wizardId=wizardId}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
1
assets/javascripts/wizard/templates/index.hbs
Normale Datei
1
assets/javascripts/wizard/templates/index.hbs
Normale Datei
|
@ -0,0 +1 @@
|
||||||
|
{{outlet}}
|
3
assets/javascripts/wizard/templates/wizard-index.hbs
Normale Datei
3
assets/javascripts/wizard/templates/wizard-index.hbs
Normale Datei
|
@ -0,0 +1,3 @@
|
||||||
|
{{#if noAccess}}
|
||||||
|
{{wizard-no-access text=(wizard-i18n noAccessI18nKey) wizardId=wizardId reason=noAccessReason}}
|
||||||
|
{{/if}}
|
|
@ -1,7 +1,3 @@
|
||||||
{{#if showCanvas}}
|
|
||||||
{{wizard-canvas}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="wizard-column">
|
<div class="wizard-column">
|
||||||
<div class="wizard-column-contents">
|
<div class="wizard-column-contents">
|
||||||
{{outlet}}
|
{{outlet}}
|
135
assets/javascripts/wizard/tests/acceptance/field-test.js.es6
Normale Datei
135
assets/javascripts/wizard/tests/acceptance/field-test.js.es6
Normale Datei
|
@ -0,0 +1,135 @@
|
||||||
|
import {
|
||||||
|
visit,
|
||||||
|
click,
|
||||||
|
fillIn,
|
||||||
|
triggerKeyEvent
|
||||||
|
} from "@ember/test-helpers";
|
||||||
|
import { test } from "qunit";
|
||||||
|
import { exists } from "../helpers/test";
|
||||||
|
import acceptance, {
|
||||||
|
query,
|
||||||
|
count,
|
||||||
|
visible,
|
||||||
|
server
|
||||||
|
} from "../helpers/acceptance";
|
||||||
|
import {
|
||||||
|
allFieldsWizard,
|
||||||
|
getWizard
|
||||||
|
} from "../helpers/wizard";
|
||||||
|
import tagsJson from "../fixtures/tags";
|
||||||
|
import usersJson from "../fixtures/users";
|
||||||
|
import { response } from "../pretender";
|
||||||
|
|
||||||
|
acceptance("Field | Fields", [ getWizard(allFieldsWizard) ],
|
||||||
|
function(hooks) {
|
||||||
|
test("Text", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(exists(".wizard-field.text-field input.wizard-focusable"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Textarea", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.textarea-field textarea.wizard-focusable"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Composer", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.composer-field .wizard-field-composer textarea"));
|
||||||
|
assert.strictEqual(count(".wizard-field.composer-field .d-editor-button-bar button"), 8);
|
||||||
|
assert.ok(visible(".wizard-btn.toggle-preview"));
|
||||||
|
|
||||||
|
await fillIn(".wizard-field.composer-field .wizard-field-composer textarea", "Input in composer");
|
||||||
|
await click(".wizard-btn.toggle-preview");
|
||||||
|
assert.strictEqual(query('.wizard-field.composer-field .wizard-field-composer .d-editor-preview-wrapper p').textContent.trim(), "Input in composer");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Text Only", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.text-only-field label.field-label"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Date", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.date-field input.date-picker"));
|
||||||
|
await click(".wizard-field.date-field input.date-picker");
|
||||||
|
assert.ok(visible(".wizard-field.date-field .pika-single"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Time", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.time-field .d-time-input .select-kit"));
|
||||||
|
await click(".wizard-field.time-field .d-time-input .select-kit .select-kit-header");
|
||||||
|
assert.ok(visible(".wizard-field.time-field .select-kit-collection"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Date Time", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.date-time-field .d-date-time-input .select-kit"));
|
||||||
|
await click(".wizard-field.date-time-field .d-date-input input.date-picker");
|
||||||
|
assert.ok(visible(".wizard-field.date-time-field .d-date-input .pika-single"));
|
||||||
|
await click(".wizard-field.date-time-field .d-time-input .select-kit .select-kit-header");
|
||||||
|
assert.ok(visible(".wizard-field.date-time-field .select-kit-collection"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Number", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.number-field input[type='number']"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Checkbox", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.checkbox-field input[type='checkbox']"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Url", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.url-field input[type='text']"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Upload", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.upload-field label.wizard-btn-upload-file"));
|
||||||
|
assert.ok(exists(".wizard-field.upload-field input.hidden-upload-field"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Dropdown", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.dropdown-field .single-select-header"));
|
||||||
|
await click(".wizard-field.dropdown-field .select-kit-header");
|
||||||
|
assert.strictEqual(count(".wizard-field.dropdown-field .select-kit-collection li"), 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Tag", async function (assert) {
|
||||||
|
server.get("/tags/filter/search", () => (response(200, { results: tagsJson['tags']})));
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.tag-field .multi-select-header"));
|
||||||
|
await click(".wizard-field.tag-field .select-kit-header");
|
||||||
|
assert.strictEqual(count(".wizard-field.tag-field .select-kit-collection li"), 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Category", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.category-field .multi-select-header"));
|
||||||
|
await click(".wizard-field.category-field .select-kit-header");
|
||||||
|
assert.strictEqual(count(".wizard-field.category-field .select-kit-collection li"), 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Group", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible(".wizard-field.group-field .single-select-header"));
|
||||||
|
await click(".wizard-field.group-field .select-kit-header");
|
||||||
|
assert.strictEqual(count(".wizard-field.group-field .select-kit-collection li"), 10);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User", async function (assert) {
|
||||||
|
server.get("/u/search/users", () => (response(200, usersJson)));
|
||||||
|
|
||||||
|
await visit("/wizard");
|
||||||
|
await fillIn(".wizard-field.user-selector-field input.ember-text-field", "a");
|
||||||
|
await triggerKeyEvent(".wizard-field.user-selector-field input.ember-text-field", "keyup", "a".charCodeAt(0));
|
||||||
|
|
||||||
|
assert.ok(visible(".wizard-field.user-selector-field .ac-wrap"));
|
||||||
|
// TODO: add assertion for ac results. autocomplete does not appear in time.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
47
assets/javascripts/wizard/tests/acceptance/step-test.js.es6
Normale Datei
47
assets/javascripts/wizard/tests/acceptance/step-test.js.es6
Normale Datei
|
@ -0,0 +1,47 @@
|
||||||
|
import { visit, click } from "@ember/test-helpers";
|
||||||
|
import { test } from "qunit";
|
||||||
|
import { exists } from "../helpers/test";
|
||||||
|
import acceptance, {
|
||||||
|
query,
|
||||||
|
count,
|
||||||
|
visible
|
||||||
|
} from "../helpers/acceptance";
|
||||||
|
import {
|
||||||
|
stepNotPermitted,
|
||||||
|
wizard,
|
||||||
|
getWizard
|
||||||
|
} from "../helpers/wizard";
|
||||||
|
import {
|
||||||
|
saveStep,
|
||||||
|
update
|
||||||
|
} from "../helpers/step";
|
||||||
|
|
||||||
|
acceptance("Step | Not permitted", [ getWizard(stepNotPermitted) ],
|
||||||
|
function(hooks) {
|
||||||
|
test("Shows not permitted message", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(exists(".step-message.not-permitted"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
acceptance("Step | Step", [ getWizard(wizard), saveStep(update) ],
|
||||||
|
function(hooks) {
|
||||||
|
test("Renders the step", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.strictEqual(query('.wizard-step-title p').textContent.trim(), "Text");
|
||||||
|
assert.strictEqual(query('.wizard-step-description p').textContent.trim(), "Text inputs!");
|
||||||
|
assert.strictEqual(query('.wizard-step-description p').textContent.trim(), "Text inputs!");
|
||||||
|
assert.strictEqual(count('.wizard-step-form .wizard-field'), 6);
|
||||||
|
assert.ok(visible('.wizard-step-footer .wizard-progress'), true);
|
||||||
|
assert.ok(visible('.wizard-step-footer .wizard-buttons'), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Goes to the next step", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible('.wizard-step.step_1'), true);
|
||||||
|
await click('.wizard-btn.next');
|
||||||
|
assert.ok(visible('.wizard-step.step_2'), true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
72
assets/javascripts/wizard/tests/acceptance/wizard-test.js.es6
Normale Datei
72
assets/javascripts/wizard/tests/acceptance/wizard-test.js.es6
Normale Datei
|
@ -0,0 +1,72 @@
|
||||||
|
import { visit } from "@ember/test-helpers";
|
||||||
|
import { test } from "qunit";
|
||||||
|
import { exists } from "../helpers/test";
|
||||||
|
import acceptance, {
|
||||||
|
query,
|
||||||
|
count,
|
||||||
|
visible
|
||||||
|
} from "../helpers/acceptance";
|
||||||
|
import {
|
||||||
|
wizardNoUser,
|
||||||
|
wizardNotPermitted,
|
||||||
|
wizardCompleted,
|
||||||
|
wizard,
|
||||||
|
getWizard
|
||||||
|
} from "../helpers/wizard";
|
||||||
|
|
||||||
|
acceptance("Wizard | Not logged in", [ getWizard(wizardNoUser) ],
|
||||||
|
function(hooks) {
|
||||||
|
test("Wizard no access requires login", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(exists(".wizard-no-access.requires-login"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
acceptance("Wizard | Not permitted", [ getWizard(wizardNotPermitted) ],
|
||||||
|
function(hooks) {
|
||||||
|
test("Wizard no access not permitted", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(exists(".wizard-no-access.not-permitted"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
acceptance("Wizard | Completed", [ getWizard(wizardCompleted) ],
|
||||||
|
function(hooks) {
|
||||||
|
test("Wizard no access completed", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(exists(".wizard-no-access.completed"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
acceptance("Wizard | Wizard", [ getWizard(wizard) ],
|
||||||
|
function(hooks) {
|
||||||
|
test("Starts", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(query('.wizard-column'), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Applies the body background color", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok($("body")[0].style.background);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Renders the wizard form", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.ok(visible('.wizard-column-contents .wizard-step'), true);
|
||||||
|
assert.ok(visible('.wizard-footer img'), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Renders the first step", async function (assert) {
|
||||||
|
await visit("/wizard");
|
||||||
|
assert.strictEqual(query('.wizard-step-title p').textContent.trim(), "Text");
|
||||||
|
assert.strictEqual(query('.wizard-step-description p').textContent.trim(), "Text inputs!");
|
||||||
|
assert.strictEqual(query('.wizard-step-description p').textContent.trim(), "Text inputs!");
|
||||||
|
assert.strictEqual(count('.wizard-step-form .wizard-field'), 6);
|
||||||
|
assert.ok(visible('.wizard-step-footer .wizard-progress'), true);
|
||||||
|
assert.ok(visible('.wizard-step-footer .wizard-buttons'), true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
17
assets/javascripts/wizard/tests/bootstrap.js.es6
Normale Datei
17
assets/javascripts/wizard/tests/bootstrap.js.es6
Normale Datei
|
@ -0,0 +1,17 @@
|
||||||
|
// discourse-skip-module
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
document.body.insertAdjacentHTML(
|
||||||
|
"afterbegin",
|
||||||
|
`
|
||||||
|
<div id="ember-testing-container"><div id="ember-testing"></div></div>
|
||||||
|
<style>#ember-testing-container { position: absolute; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; } #ember-testing { zoom: 50%; }</style>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(requirejs.entries).forEach(function (entry) {
|
||||||
|
if (/\-test/.test(entry)) {
|
||||||
|
requirejs(entry);
|
||||||
|
}
|
||||||
|
});
|
209
assets/javascripts/wizard/tests/fixtures/categories.js.es6
gevendort
Normale Datei
209
assets/javascripts/wizard/tests/fixtures/categories.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,209 @@
|
||||||
|
export default {
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Uncategorized",
|
||||||
|
"color": "0088CC",
|
||||||
|
"text_color": "FFFFFF",
|
||||||
|
"slug": "uncategorized",
|
||||||
|
"topic_count": 1,
|
||||||
|
"post_count": 1,
|
||||||
|
"position": 0,
|
||||||
|
"description": "Topics that don't need a category, or don't fit into any other existing category.",
|
||||||
|
"description_text": "Topics that don't need a category, or don't fit into any other existing category.",
|
||||||
|
"description_excerpt": "Topics that don't need a category, or don't fit into any other existing category.",
|
||||||
|
"topic_url": "/t/",
|
||||||
|
"read_restricted": false,
|
||||||
|
"permission": 1,
|
||||||
|
"notification_level": 0,
|
||||||
|
"topic_template": null,
|
||||||
|
"has_children": false,
|
||||||
|
"sort_order": null,
|
||||||
|
"sort_ascending": null,
|
||||||
|
"show_subcategory_list": false,
|
||||||
|
"num_featured_topics": 3,
|
||||||
|
"default_view": null,
|
||||||
|
"subcategory_list_style": "rows_with_featured_topics",
|
||||||
|
"default_top_period": "all",
|
||||||
|
"default_list_filter": "all",
|
||||||
|
"minimum_required_tags": 0,
|
||||||
|
"navigate_to_first_post_after_read": false,
|
||||||
|
"custom_fields": {
|
||||||
|
"create_topic_wizard": null
|
||||||
|
},
|
||||||
|
"allowed_tags": [],
|
||||||
|
"allowed_tag_groups": [],
|
||||||
|
"allow_global_tags": false,
|
||||||
|
"min_tags_from_required_group": 1,
|
||||||
|
"required_tag_group_name": null,
|
||||||
|
"read_only_banner": null,
|
||||||
|
"uploaded_logo": null,
|
||||||
|
"uploaded_background": null,
|
||||||
|
"can_edit": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "Site Feedback",
|
||||||
|
"color": "808281",
|
||||||
|
"text_color": "FFFFFF",
|
||||||
|
"slug": "site-feedback",
|
||||||
|
"topic_count": 20,
|
||||||
|
"post_count": 21,
|
||||||
|
"position": 1,
|
||||||
|
"description": "<p>Discussion about this site, its organization, how it works, and how we can improve it.</p>",
|
||||||
|
"description_text": "Discussion about this site, its organization, how it works, and how we can improve it.",
|
||||||
|
"description_excerpt": "Discussion about this site, its organization, how it works, and how we can improve it.",
|
||||||
|
"topic_url": "/t/about-the-site-feedback-category/1",
|
||||||
|
"read_restricted": false,
|
||||||
|
"permission": 1,
|
||||||
|
"notification_level": 0,
|
||||||
|
"topic_template": null,
|
||||||
|
"has_children": false,
|
||||||
|
"sort_order": null,
|
||||||
|
"sort_ascending": null,
|
||||||
|
"show_subcategory_list": false,
|
||||||
|
"num_featured_topics": 3,
|
||||||
|
"default_view": null,
|
||||||
|
"subcategory_list_style": "rows_with_featured_topics",
|
||||||
|
"default_top_period": "all",
|
||||||
|
"default_list_filter": "all",
|
||||||
|
"minimum_required_tags": 0,
|
||||||
|
"navigate_to_first_post_after_read": false,
|
||||||
|
"custom_fields": {
|
||||||
|
"create_topic_wizard": null
|
||||||
|
},
|
||||||
|
"allowed_tags": [],
|
||||||
|
"allowed_tag_groups": [],
|
||||||
|
"allow_global_tags": false,
|
||||||
|
"min_tags_from_required_group": 1,
|
||||||
|
"required_tag_group_name": null,
|
||||||
|
"read_only_banner": null,
|
||||||
|
"uploaded_logo": null,
|
||||||
|
"uploaded_background": null,
|
||||||
|
"can_edit": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"name": "Staff",
|
||||||
|
"color": "E45735",
|
||||||
|
"text_color": "FFFFFF",
|
||||||
|
"slug": "staff",
|
||||||
|
"topic_count": 4,
|
||||||
|
"post_count": 7,
|
||||||
|
"position": 2,
|
||||||
|
"description": "<p>Private category for staff discussions. Topics are only visible to admins and moderators.</p>",
|
||||||
|
"description_text": "Private category for staff discussions. Topics are only visible to admins and moderators.",
|
||||||
|
"description_excerpt": "Private category for staff discussions. Topics are only visible to admins and moderators.",
|
||||||
|
"topic_url": "/t/about-the-staff-category/2",
|
||||||
|
"read_restricted": true,
|
||||||
|
"permission": 1,
|
||||||
|
"notification_level": 0,
|
||||||
|
"topic_template": null,
|
||||||
|
"has_children": false,
|
||||||
|
"sort_order": null,
|
||||||
|
"sort_ascending": null,
|
||||||
|
"show_subcategory_list": false,
|
||||||
|
"num_featured_topics": 3,
|
||||||
|
"default_view": null,
|
||||||
|
"subcategory_list_style": "rows_with_featured_topics",
|
||||||
|
"default_top_period": "all",
|
||||||
|
"default_list_filter": "all",
|
||||||
|
"minimum_required_tags": 0,
|
||||||
|
"navigate_to_first_post_after_read": false,
|
||||||
|
"custom_fields": {
|
||||||
|
"create_topic_wizard": null
|
||||||
|
},
|
||||||
|
"allowed_tags": [],
|
||||||
|
"allowed_tag_groups": [],
|
||||||
|
"allow_global_tags": false,
|
||||||
|
"min_tags_from_required_group": 1,
|
||||||
|
"required_tag_group_name": null,
|
||||||
|
"read_only_banner": null,
|
||||||
|
"uploaded_logo": null,
|
||||||
|
"uploaded_background": null,
|
||||||
|
"can_edit": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "Lounge",
|
||||||
|
"color": "A461EF",
|
||||||
|
"text_color": "652D90",
|
||||||
|
"slug": "lounge",
|
||||||
|
"topic_count": 1,
|
||||||
|
"post_count": 1,
|
||||||
|
"position": 3,
|
||||||
|
"description": "<p>A category exclusive to members with trust level 3 and higher.</p>",
|
||||||
|
"description_text": "A category exclusive to members with trust level 3 and higher.",
|
||||||
|
"description_excerpt": "A category exclusive to members with trust level 3 and higher.",
|
||||||
|
"topic_url": "/t/about-the-lounge-category/3",
|
||||||
|
"read_restricted": true,
|
||||||
|
"permission": 1,
|
||||||
|
"notification_level": 0,
|
||||||
|
"topic_template": null,
|
||||||
|
"has_children": false,
|
||||||
|
"sort_order": null,
|
||||||
|
"sort_ascending": null,
|
||||||
|
"show_subcategory_list": false,
|
||||||
|
"num_featured_topics": 3,
|
||||||
|
"default_view": null,
|
||||||
|
"subcategory_list_style": "rows_with_featured_topics",
|
||||||
|
"default_top_period": "all",
|
||||||
|
"default_list_filter": "all",
|
||||||
|
"minimum_required_tags": 0,
|
||||||
|
"navigate_to_first_post_after_read": false,
|
||||||
|
"custom_fields": {
|
||||||
|
"create_topic_wizard": null
|
||||||
|
},
|
||||||
|
"allowed_tags": [],
|
||||||
|
"allowed_tag_groups": [],
|
||||||
|
"allow_global_tags": false,
|
||||||
|
"min_tags_from_required_group": 1,
|
||||||
|
"required_tag_group_name": null,
|
||||||
|
"read_only_banner": null,
|
||||||
|
"uploaded_logo": null,
|
||||||
|
"uploaded_background": null,
|
||||||
|
"can_edit": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"name": "Custom Categories",
|
||||||
|
"color": "0088CC",
|
||||||
|
"text_color": "FFFFFF",
|
||||||
|
"slug": "custom-category",
|
||||||
|
"topic_count": 0,
|
||||||
|
"post_count": 0,
|
||||||
|
"position": 10,
|
||||||
|
"description": "Description of custom category",
|
||||||
|
"description_text": "Description of custom category",
|
||||||
|
"description_excerpt": "Description of custom category",
|
||||||
|
"topic_url": "/t/about-the-custom-category/5",
|
||||||
|
"read_restricted": false,
|
||||||
|
"permission": 1,
|
||||||
|
"notification_level": 0,
|
||||||
|
"topic_template": null,
|
||||||
|
"has_children": false,
|
||||||
|
"sort_order": null,
|
||||||
|
"sort_ascending": null,
|
||||||
|
"show_subcategory_list": false,
|
||||||
|
"num_featured_topics": 3,
|
||||||
|
"default_view": null,
|
||||||
|
"subcategory_list_style": "rows_with_featured_topics",
|
||||||
|
"default_top_period": "all",
|
||||||
|
"default_list_filter": "all",
|
||||||
|
"minimum_required_tags": 0,
|
||||||
|
"navigate_to_first_post_after_read": false,
|
||||||
|
"custom_fields": {
|
||||||
|
"create_topic_wizard": null
|
||||||
|
},
|
||||||
|
"allowed_tags": [],
|
||||||
|
"allowed_tag_groups": [],
|
||||||
|
"allow_global_tags": false,
|
||||||
|
"min_tags_from_required_group": 1,
|
||||||
|
"required_tag_group_name": null,
|
||||||
|
"read_only_banner": null,
|
||||||
|
"uploaded_logo": null,
|
||||||
|
"uploaded_background": null,
|
||||||
|
"can_edit": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
313
assets/javascripts/wizard/tests/fixtures/groups.js.es6
gevendort
Normale Datei
313
assets/javascripts/wizard/tests/fixtures/groups.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,313 @@
|
||||||
|
export default {
|
||||||
|
"groups": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "admins",
|
||||||
|
"display_name": "admins",
|
||||||
|
"user_count": 1,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "everyone",
|
||||||
|
"display_name": "everyone",
|
||||||
|
"user_count": 0,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 3,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 15,
|
||||||
|
"automatic": false,
|
||||||
|
"name": "custom_group",
|
||||||
|
"user_count": 1,
|
||||||
|
"mentionable_level": 1,
|
||||||
|
"messageable_level": 2,
|
||||||
|
"visibility_level": 3,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": "Custom Group",
|
||||||
|
"grant_trust_level": 3,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": "I am prefilled",
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 99,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "moderators",
|
||||||
|
"display_name": "moderators",
|
||||||
|
"user_count": 0,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 99,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 2,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "staff",
|
||||||
|
"display_name": "staff",
|
||||||
|
"user_count": 1,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "trust_level_0",
|
||||||
|
"display_name": "trust_level_0",
|
||||||
|
"user_count": 2,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 11,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "trust_level_1",
|
||||||
|
"display_name": "trust_level_1",
|
||||||
|
"user_count": 2,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 12,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "trust_level_2",
|
||||||
|
"display_name": "trust_level_2",
|
||||||
|
"user_count": 1,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "trust_level_3",
|
||||||
|
"display_name": "trust_level_3",
|
||||||
|
"user_count": 1,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 14,
|
||||||
|
"automatic": true,
|
||||||
|
"name": "trust_level_4",
|
||||||
|
"display_name": "trust_level_4",
|
||||||
|
"user_count": 0,
|
||||||
|
"mentionable_level": 0,
|
||||||
|
"messageable_level": 0,
|
||||||
|
"visibility_level": 1,
|
||||||
|
"primary_group": false,
|
||||||
|
"title": null,
|
||||||
|
"grant_trust_level": null,
|
||||||
|
"incoming_email": null,
|
||||||
|
"has_messages": false,
|
||||||
|
"flair_url": null,
|
||||||
|
"flair_bg_color": null,
|
||||||
|
"flair_color": null,
|
||||||
|
"bio_raw": null,
|
||||||
|
"bio_cooked": null,
|
||||||
|
"bio_excerpt": null,
|
||||||
|
"public_admission": false,
|
||||||
|
"public_exit": false,
|
||||||
|
"allow_membership_requests": false,
|
||||||
|
"full_name": null,
|
||||||
|
"default_notification_level": 3,
|
||||||
|
"membership_request_template": null,
|
||||||
|
"members_visibility_level": 0,
|
||||||
|
"can_see_members": true,
|
||||||
|
"can_admin_group": true,
|
||||||
|
"publish_read_state": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
283
assets/javascripts/wizard/tests/fixtures/site-settings.js.es6
gevendort
Normale Datei
283
assets/javascripts/wizard/tests/fixtures/site-settings.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,283 @@
|
||||||
|
export default {
|
||||||
|
"default_locale": "en",
|
||||||
|
"title": "Discourse",
|
||||||
|
"short_site_description": "",
|
||||||
|
"exclude_rel_nofollow_domains": "",
|
||||||
|
"logo": "/images/discourse-logo-sketch.png",
|
||||||
|
"logo_small": "/images/discourse-logo-sketch-small.png",
|
||||||
|
"digest_logo": "",
|
||||||
|
"mobile_logo": "",
|
||||||
|
"logo_dark": "",
|
||||||
|
"logo_small_dark": "",
|
||||||
|
"mobile_logo_dark": "",
|
||||||
|
"large_icon": "",
|
||||||
|
"favicon": "",
|
||||||
|
"apple_touch_icon": "",
|
||||||
|
"display_local_time_in_user_card": false,
|
||||||
|
"allow_user_locale": false,
|
||||||
|
"set_locale_from_accept_language_header": false,
|
||||||
|
"support_mixed_text_direction": false,
|
||||||
|
"suggested_topics": 5,
|
||||||
|
"ga_universal_tracking_code": "",
|
||||||
|
"ga_universal_domain_name": "auto",
|
||||||
|
"gtm_container_id": "",
|
||||||
|
"top_menu": "categories|latest",
|
||||||
|
"post_menu": "read|like|share|flag|edit|bookmark|delete|admin|reply",
|
||||||
|
"post_menu_hidden_items": "flag|bookmark|edit|delete|admin",
|
||||||
|
"share_links": "twitter|facebook|email",
|
||||||
|
"share_quote_visibility": "anonymous",
|
||||||
|
"share_quote_buttons": "twitter|email",
|
||||||
|
"desktop_category_page_style": "categories_and_latest_topics",
|
||||||
|
"category_colors": "BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|E45735",
|
||||||
|
"category_style": "bullet",
|
||||||
|
"max_category_nesting": 2,
|
||||||
|
"enable_mobile_theme": true,
|
||||||
|
"enable_direct_s3_uploads": false,
|
||||||
|
"enable_upload_debug_mode": false,
|
||||||
|
"default_dark_mode_color_scheme_id": 1,
|
||||||
|
"relative_date_duration": 30,
|
||||||
|
"fixed_category_positions": false,
|
||||||
|
"fixed_category_positions_on_create": false,
|
||||||
|
"enable_badges": true,
|
||||||
|
"enable_badge_sql": true,
|
||||||
|
"max_favorite_badges": 2,
|
||||||
|
"enable_whispers": false,
|
||||||
|
"enable_bookmarks_with_reminders": true,
|
||||||
|
"push_notifications_prompt": true,
|
||||||
|
"vapid_public_key_bytes": "4|29|219|88|202|66|198|62|182|204|66|176|229|200|131|26|141|21|178|231|150|161|2|128|228|200|179|126|118|232|196|19|232|76|108|189|54|211|210|155|55|228|173|112|38|158|114|127|18|95|7|56|110|183|192|92|43|0|243|249|233|89|9|207|255",
|
||||||
|
"invite_only": false,
|
||||||
|
"login_required": false,
|
||||||
|
"must_approve_users": false,
|
||||||
|
"enable_local_logins": true,
|
||||||
|
"enable_local_logins_via_email": true,
|
||||||
|
"allow_new_registrations": true,
|
||||||
|
"enable_signup_cta": true,
|
||||||
|
"facebook_app_id": "",
|
||||||
|
"auth_skip_create_confirm": false,
|
||||||
|
"auth_overrides_email": false,
|
||||||
|
"enable_discourse_connect": true,
|
||||||
|
"discourse_connect_overrides_avatar": false,
|
||||||
|
"hide_email_address_taken": false,
|
||||||
|
"min_username_length": 3,
|
||||||
|
"max_username_length": 20,
|
||||||
|
"unicode_usernames": false,
|
||||||
|
"min_password_length": 10,
|
||||||
|
"min_admin_password_length": 15,
|
||||||
|
"email_editable": true,
|
||||||
|
"logout_redirect": "",
|
||||||
|
"full_name_required": false,
|
||||||
|
"enable_names": true,
|
||||||
|
"invite_expiry_days": 90,
|
||||||
|
"invites_per_page": 40,
|
||||||
|
"delete_user_max_post_age": 60,
|
||||||
|
"delete_all_posts_max": 15,
|
||||||
|
"prioritize_username_in_ux": true,
|
||||||
|
"enable_user_directory": true,
|
||||||
|
"allow_anonymous_posting": false,
|
||||||
|
"anonymous_posting_min_trust_level": 1,
|
||||||
|
"allow_users_to_hide_profile": true,
|
||||||
|
"hide_user_profiles_from_public": false,
|
||||||
|
"allow_featured_topic_on_user_profiles": true,
|
||||||
|
"hide_suspension_reasons": false,
|
||||||
|
"ignored_users_count_message_threshold": 5,
|
||||||
|
"ignored_users_message_gap_days": 365,
|
||||||
|
"user_selected_primary_groups": false,
|
||||||
|
"gravatar_name": "Gravatar",
|
||||||
|
"gravatar_base_url": "www.gravatar.com",
|
||||||
|
"gravatar_login_url": "/emails",
|
||||||
|
"enable_group_directory": true,
|
||||||
|
"enable_category_group_moderation": false,
|
||||||
|
"min_post_length": 20,
|
||||||
|
"min_first_post_length": 20,
|
||||||
|
"min_personal_message_post_length": 10,
|
||||||
|
"max_post_length": 32000,
|
||||||
|
"topic_featured_link_enabled": true,
|
||||||
|
"min_topic_views_for_delete_confirm": 5000,
|
||||||
|
"min_topic_title_length": 15,
|
||||||
|
"max_topic_title_length": 255,
|
||||||
|
"enable_filtered_replies_view": false,
|
||||||
|
"min_personal_message_title_length": 2,
|
||||||
|
"allow_uncategorized_topics": true,
|
||||||
|
"min_title_similar_length": 10,
|
||||||
|
"enable_personal_messages": true,
|
||||||
|
"edit_history_visible_to_public": true,
|
||||||
|
"delete_removed_posts_after": 24,
|
||||||
|
"traditional_markdown_linebreaks": false,
|
||||||
|
"enable_markdown_typographer": true,
|
||||||
|
"enable_markdown_linkify": true,
|
||||||
|
"markdown_linkify_tlds": "com|net|org|io|onion|co|tv|ru|cn|us|uk|me|de|fr|fi|gov",
|
||||||
|
"markdown_typographer_quotation_marks": "“|”|‘|’",
|
||||||
|
"enable_rich_text_paste": true,
|
||||||
|
"suppress_reply_directly_below": true,
|
||||||
|
"suppress_reply_directly_above": true,
|
||||||
|
"max_reply_history": 1,
|
||||||
|
"enable_mentions": true,
|
||||||
|
"here_mention": "here",
|
||||||
|
"newuser_max_embedded_media": 1,
|
||||||
|
"newuser_max_attachments": 0,
|
||||||
|
"show_pinned_excerpt_mobile": true,
|
||||||
|
"show_pinned_excerpt_desktop": true,
|
||||||
|
"display_name_on_posts": false,
|
||||||
|
"show_time_gap_days": 7,
|
||||||
|
"short_progress_text_threshold": 10000,
|
||||||
|
"default_code_lang": "auto",
|
||||||
|
"autohighlight_all_code": false,
|
||||||
|
"highlighted_languages": "apache|bash|cs|cpp|css|coffeescript|diff|xml|http|ini|json|java|javascript|makefile|markdown|nginx|objectivec|ruby|perl|php|python|sql|handlebars",
|
||||||
|
"show_copy_button_on_codeblocks": false,
|
||||||
|
"enable_emoji": true,
|
||||||
|
"enable_emoji_shortcuts": true,
|
||||||
|
"emoji_set": "twitter",
|
||||||
|
"emoji_autocomplete_min_chars": 0,
|
||||||
|
"enable_inline_emoji_translation": false,
|
||||||
|
"code_formatting_style": "code-fences",
|
||||||
|
"allowed_href_schemes": "",
|
||||||
|
"watched_words_regular_expressions": false,
|
||||||
|
"enable_diffhtml_preview": false,
|
||||||
|
"enable_fast_edit": true,
|
||||||
|
"old_post_notice_days": 14,
|
||||||
|
"blur_tl0_flagged_posts_media": true,
|
||||||
|
"email_time_window_mins": 10,
|
||||||
|
"disable_digest_emails": false,
|
||||||
|
"email_in": false,
|
||||||
|
"enable_imap": false,
|
||||||
|
"enable_smtp": false,
|
||||||
|
"disable_emails": "no",
|
||||||
|
"bounce_score_threshold": 4,
|
||||||
|
"enable_secondary_emails": true,
|
||||||
|
"max_image_size_kb": 4096,
|
||||||
|
"max_attachment_size_kb": 4096,
|
||||||
|
"authorized_extensions": "jpg|jpeg|png|gif|heic|heif|webp",
|
||||||
|
"authorized_extensions_for_staff": "",
|
||||||
|
"max_image_width": 690,
|
||||||
|
"max_image_height": 500,
|
||||||
|
"prevent_anons_from_downloading_files": false,
|
||||||
|
"secure_media": false,
|
||||||
|
"enable_s3_uploads": false,
|
||||||
|
"allow_profile_backgrounds": true,
|
||||||
|
"allow_uploaded_avatars": "0",
|
||||||
|
"default_avatars": "",
|
||||||
|
"external_system_avatars_enabled": true,
|
||||||
|
"external_system_avatars_url": "/letter_avatar_proxy/v4/letter/{first_letter}/{color}/{size}.png",
|
||||||
|
"external_emoji_url": "",
|
||||||
|
"selectable_avatars_mode": "disabled",
|
||||||
|
"selectable_avatars": "",
|
||||||
|
"allow_staff_to_upload_any_file_in_pm": true,
|
||||||
|
"simultaneous_uploads": 5,
|
||||||
|
"composer_media_optimization_image_enabled": true,
|
||||||
|
"composer_media_optimization_image_bytes_optimization_threshold": 524288,
|
||||||
|
"composer_media_optimization_image_resize_dimensions_threshold": 1920,
|
||||||
|
"composer_media_optimization_image_resize_width_target": 1920,
|
||||||
|
"composer_media_optimization_image_resize_pre_multiply": false,
|
||||||
|
"composer_media_optimization_image_resize_linear_rgb": false,
|
||||||
|
"composer_media_optimization_image_encode_quality": 75,
|
||||||
|
"composer_media_optimization_debug_mode": false,
|
||||||
|
"min_trust_level_to_allow_profile_background": 0,
|
||||||
|
"min_trust_level_to_allow_user_card_background": 0,
|
||||||
|
"min_trust_level_to_allow_ignore": 2,
|
||||||
|
"tl1_requires_read_posts": 30,
|
||||||
|
"tl3_links_no_follow": false,
|
||||||
|
"enforce_second_factor": "no",
|
||||||
|
"moderators_change_post_ownership": false,
|
||||||
|
"moderators_view_emails": false,
|
||||||
|
"use_admin_ip_allowlist": false,
|
||||||
|
"allowed_iframes": "https://www.google.com/maps/embed?|https://www.openstreetmap.org/export/embed.html?|https://calendar.google.com/calendar/embed?|https://codepen.io/|https://www.instagram.com|http://localhost:3000/discobot/certificate.svg",
|
||||||
|
"can_permanently_delete": false,
|
||||||
|
"max_oneboxes_per_post": 50,
|
||||||
|
"reviewable_claiming": "disabled",
|
||||||
|
"reviewable_default_topics": false,
|
||||||
|
"reviewable_default_visibility": "low",
|
||||||
|
"alert_admins_if_errors_per_minute": 0,
|
||||||
|
"alert_admins_if_errors_per_hour": 0,
|
||||||
|
"max_prints_per_hour_per_user": 5,
|
||||||
|
"invite_link_max_redemptions_limit": 5000,
|
||||||
|
"invite_link_max_redemptions_limit_users": 10,
|
||||||
|
"enable_long_polling": true,
|
||||||
|
"enable_chunked_encoding": true,
|
||||||
|
"long_polling_base_url": "/",
|
||||||
|
"background_polling_interval": 60000,
|
||||||
|
"polling_interval": 3000,
|
||||||
|
"anon_polling_interval": 25000,
|
||||||
|
"flush_timings_secs": 60,
|
||||||
|
"verbose_localization": false,
|
||||||
|
"max_new_topics": 500,
|
||||||
|
"enable_safe_mode": true,
|
||||||
|
"tos_url": "",
|
||||||
|
"privacy_policy_url": "",
|
||||||
|
"faq_url": "",
|
||||||
|
"enable_backups": true,
|
||||||
|
"backup_location": "local",
|
||||||
|
"maximum_backups": 5,
|
||||||
|
"use_pg_headlines_for_excerpt": false,
|
||||||
|
"min_search_term_length": 3,
|
||||||
|
"log_search_queries": true,
|
||||||
|
"version_checks": true,
|
||||||
|
"suppress_uncategorized_badge": true,
|
||||||
|
"header_dropdown_category_count": 8,
|
||||||
|
"slug_generation_method": "ascii",
|
||||||
|
"summary_timeline_button": false,
|
||||||
|
"topic_views_heat_low": 1000,
|
||||||
|
"topic_views_heat_medium": 2000,
|
||||||
|
"topic_views_heat_high": 3500,
|
||||||
|
"topic_post_like_heat_low": 0.5,
|
||||||
|
"topic_post_like_heat_medium": 1,
|
||||||
|
"topic_post_like_heat_high": 2,
|
||||||
|
"history_hours_low": 12,
|
||||||
|
"history_hours_medium": 24,
|
||||||
|
"history_hours_high": 48,
|
||||||
|
"cold_age_days_low": 14,
|
||||||
|
"cold_age_days_medium": 90,
|
||||||
|
"cold_age_days_high": 180,
|
||||||
|
"global_notice": "",
|
||||||
|
"show_create_topics_notice": true,
|
||||||
|
"bootstrap_mode_min_users": 50,
|
||||||
|
"bootstrap_mode_enabled": true,
|
||||||
|
"automatically_unpin_topics": true,
|
||||||
|
"read_time_word_count": 500,
|
||||||
|
"topic_page_title_includes_category": true,
|
||||||
|
"svg_icon_subset": "",
|
||||||
|
"allow_bulk_invite": true,
|
||||||
|
"disable_mailing_list_mode": true,
|
||||||
|
"default_topics_automatic_unpin": true,
|
||||||
|
"mute_all_categories_by_default": false,
|
||||||
|
"tagging_enabled": true,
|
||||||
|
"tag_style": "simple",
|
||||||
|
"max_tags_per_topic": 5,
|
||||||
|
"max_tag_length": 20,
|
||||||
|
"min_trust_level_to_tag_topics": "0",
|
||||||
|
"max_tag_search_results": 5,
|
||||||
|
"max_tags_in_filter_list": 30,
|
||||||
|
"tags_sort_alphabetically": false,
|
||||||
|
"tags_listed_by_group": false,
|
||||||
|
"suppress_overlapping_tags_in_list": false,
|
||||||
|
"remove_muted_tags_from_latest": "always",
|
||||||
|
"force_lowercase_tags": true,
|
||||||
|
"dashboard_hidden_reports": "",
|
||||||
|
"dashboard_visible_tabs": "moderation|security|reports",
|
||||||
|
"dashboard_general_tab_activity_metrics": "page_view_total_reqs|visits|time_to_first_response|likes|flags|user_to_user_private_messages_with_replies",
|
||||||
|
"discourse_narrative_bot_enabled": true,
|
||||||
|
"details_enabled": true,
|
||||||
|
"custom_wizard_enabled": true,
|
||||||
|
"wizard_redirect_exclude_paths": "admin",
|
||||||
|
"wizard_recognised_image_upload_formats": "jpg|jpeg|png|gif",
|
||||||
|
"wizard_important_notices_on_dashboard": true,
|
||||||
|
"discourse_local_dates_email_format": "YYYY-MM-DDTHH:mm:ss[Z]",
|
||||||
|
"discourse_local_dates_enabled": true,
|
||||||
|
"discourse_local_dates_default_formats": "LLL|LTS|LL|LLLL",
|
||||||
|
"discourse_local_dates_default_timezones": "Europe/Paris|America/Los_Angeles",
|
||||||
|
"poll_enabled": true,
|
||||||
|
"poll_maximum_options": 20,
|
||||||
|
"poll_minimum_trust_level_to_create": 1,
|
||||||
|
"poll_groupable_user_fields": "",
|
||||||
|
"poll_export_data_explorer_query_id": -16,
|
||||||
|
"presence_enabled": true,
|
||||||
|
"presence_max_users_shown": 5,
|
||||||
|
"available_locales": "[{\"name\":\"اللغة العربية\",\"value\":\"ar\"},{\"name\":\"беларуская мова\",\"value\":\"be\"},{\"name\":\"български език\",\"value\":\"bg\"},{\"name\":\"bosanski jezik\",\"value\":\"bs_BA\"},{\"name\":\"català\",\"value\":\"ca\"},{\"name\":\"čeština\",\"value\":\"cs\"},{\"name\":\"dansk\",\"value\":\"da\"},{\"name\":\"Deutsch\",\"value\":\"de\"},{\"name\":\"ελληνικά\",\"value\":\"el\"},{\"name\":\"English (US)\",\"value\":\"en\"},{\"name\":\"English (UK)\",\"value\":\"en_GB\"},{\"name\":\"Español\",\"value\":\"es\"},{\"name\":\"eesti\",\"value\":\"et\"},{\"name\":\"فارسی\",\"value\":\"fa_IR\"},{\"name\":\"suomi\",\"value\":\"fi\"},{\"name\":\"Français\",\"value\":\"fr\"},{\"name\":\"galego\",\"value\":\"gl\"},{\"name\":\"עברית\",\"value\":\"he\"},{\"name\":\"magyar\",\"value\":\"hu\"},{\"name\":\"Հայերեն\",\"value\":\"hy\"},{\"name\":\"Indonesian\",\"value\":\"id\"},{\"name\":\"Italiano\",\"value\":\"it\"},{\"name\":\"日本語\",\"value\":\"ja\"},{\"name\":\"한국어\",\"value\":\"ko\"},{\"name\":\"lietuvių kalba\",\"value\":\"lt\"},{\"name\":\"latviešu valoda\",\"value\":\"lv\"},{\"name\":\"Norsk bokmål\",\"value\":\"nb_NO\"},{\"name\":\"Nederlands\",\"value\":\"nl\"},{\"name\":\"polski\",\"value\":\"pl_PL\"},{\"name\":\"Português\",\"value\":\"pt\"},{\"name\":\"Português (BR)\",\"value\":\"pt_BR\"},{\"name\":\"limba română\",\"value\":\"ro\"},{\"name\":\"Русский\",\"value\":\"ru\"},{\"name\":\"slovenčina\",\"value\":\"sk\"},{\"name\":\"slovenščina\",\"value\":\"sl\"},{\"name\":\"Shqip\",\"value\":\"sq\"},{\"name\":\"српски језик\",\"value\":\"sr\"},{\"name\":\"svenska\",\"value\":\"sv\"},{\"name\":\"Kiswahili\",\"value\":\"sw\"},{\"name\":\"తెలుగు\",\"value\":\"te\"},{\"name\":\"ไทย\",\"value\":\"th\"},{\"name\":\"Türkçe\",\"value\":\"tr_TR\"},{\"name\":\"українська мова\",\"value\":\"uk\"},{\"name\":\"اردو\",\"value\":\"ur\"},{\"name\":\"Việt Nam\",\"value\":\"vi\"},{\"name\":\"简体中文\",\"value\":\"zh_CN\"},{\"name\":\"繁體中文\",\"value\":\"zh_TW\"}]",
|
||||||
|
"require_invite_code": false,
|
||||||
|
"site_logo_url": "http://localhost:3000/images/discourse-logo-sketch.png",
|
||||||
|
"site_logo_small_url": "http://localhost:3000/images/discourse-logo-sketch-small.png",
|
||||||
|
"site_mobile_logo_url": "http://localhost:3000/images/discourse-logo-sketch.png",
|
||||||
|
"site_favicon_url": "http://localhost:3000/uploads/default/optimized/1X/_129430568242d1b7f853bb13ebea28b3f6af4e7_2_32x32.png",
|
||||||
|
"site_logo_dark_url": "",
|
||||||
|
"site_logo_small_dark_url": "",
|
||||||
|
"site_mobile_logo_dark_url": ""
|
||||||
|
}
|
22
assets/javascripts/wizard/tests/fixtures/tags.js.es6
gevendort
Normale Datei
22
assets/javascripts/wizard/tests/fixtures/tags.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,22 @@
|
||||||
|
export default {
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"id": "tag1",
|
||||||
|
"text": "tag1",
|
||||||
|
"name": "tag1",
|
||||||
|
"description": null,
|
||||||
|
"count": 1,
|
||||||
|
"pm_count": 0,
|
||||||
|
"target_tag": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "tag2",
|
||||||
|
"text": "tag2",
|
||||||
|
"name": "tag2",
|
||||||
|
"description": null,
|
||||||
|
"count": 1,
|
||||||
|
"pm_count": 0,
|
||||||
|
"target_tag": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
5
assets/javascripts/wizard/tests/fixtures/update.js.es6
gevendort
Normale Datei
5
assets/javascripts/wizard/tests/fixtures/update.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,5 @@
|
||||||
|
export default {
|
||||||
|
"final": false,
|
||||||
|
"next_step_id": "step_2",
|
||||||
|
"wizard": {}
|
||||||
|
}
|
34
assets/javascripts/wizard/tests/fixtures/user.js.es6
gevendort
Normale Datei
34
assets/javascripts/wizard/tests/fixtures/user.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,34 @@
|
||||||
|
export default {
|
||||||
|
id: 19,
|
||||||
|
username: "angus",
|
||||||
|
uploaded_avatar_id: 5275,
|
||||||
|
avatar_template: "/user_avatar/localhost/angus/{size}/5275.png",
|
||||||
|
name: "Angus McLeod",
|
||||||
|
unread_notifications: 0,
|
||||||
|
unread_private_messages: 0,
|
||||||
|
unread_high_priority_notifications: 0,
|
||||||
|
admin: true,
|
||||||
|
notification_channel_position: null,
|
||||||
|
site_flagged_posts_count: 1,
|
||||||
|
moderator: true,
|
||||||
|
staff: true,
|
||||||
|
can_create_group: true,
|
||||||
|
title: "",
|
||||||
|
reply_count: 859,
|
||||||
|
topic_count: 36,
|
||||||
|
enable_quoting: true,
|
||||||
|
external_links_in_new_tab: false,
|
||||||
|
dynamic_favicon: true,
|
||||||
|
trust_level: 4,
|
||||||
|
can_edit: true,
|
||||||
|
can_invite_to_forum: true,
|
||||||
|
should_be_redirected_to_top: false,
|
||||||
|
custom_fields: {},
|
||||||
|
muted_category_ids: [],
|
||||||
|
dismissed_banner_key: null,
|
||||||
|
akismet_review_count: 0,
|
||||||
|
title_count_mode: "notifications",
|
||||||
|
timezone: "Australia/Perth",
|
||||||
|
skip_new_user_tips: false,
|
||||||
|
can_review: true
|
||||||
|
}
|
14
assets/javascripts/wizard/tests/fixtures/users.js.es6
gevendort
Normale Datei
14
assets/javascripts/wizard/tests/fixtures/users.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,14 @@
|
||||||
|
export default {
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"username": "angus",
|
||||||
|
"name": "Angus",
|
||||||
|
"avatar_template": "/user_avatar/localhost/angus/{size}/12_2.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "angus_2",
|
||||||
|
"name": "Angus 2",
|
||||||
|
"avatar_template": "/letter_avatar_proxy/v4/letter/a/e9a140/{size}.png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
469
assets/javascripts/wizard/tests/fixtures/wizard.js.es6
gevendort
Normale Datei
469
assets/javascripts/wizard/tests/fixtures/wizard.js.es6
gevendort
Normale Datei
|
@ -0,0 +1,469 @@
|
||||||
|
export default {
|
||||||
|
"id": "wizard",
|
||||||
|
"name": "Wizard",
|
||||||
|
"start": "step_1",
|
||||||
|
"background": "#333333",
|
||||||
|
"submission_last_updated_at": "2022-03-15T21:11:01+01:00",
|
||||||
|
"theme_id": 2,
|
||||||
|
"required": false,
|
||||||
|
"permitted": true,
|
||||||
|
"uncategorized_category_id": 1,
|
||||||
|
"categories": [],
|
||||||
|
"subscribed": false,
|
||||||
|
"resume_on_revisit": false,
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"id": "step_1",
|
||||||
|
"index": 0,
|
||||||
|
"next": "step_2",
|
||||||
|
"description": "<p>Text inputs!</p>",
|
||||||
|
"title": "Text",
|
||||||
|
"permitted": true,
|
||||||
|
"permitted_message": null,
|
||||||
|
"final": false,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "step_1_field_1",
|
||||||
|
"index": 0,
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"value": "I am prefilled",
|
||||||
|
"label": "<p>Text</p>",
|
||||||
|
"description": "Text field description.",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 1,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_1",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_2",
|
||||||
|
"index": 0,
|
||||||
|
"type": "textarea",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Textarea</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 2,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_1",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_3",
|
||||||
|
"index": 2,
|
||||||
|
"type": "composer",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Composer</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 3,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_1",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_4",
|
||||||
|
"index": 3,
|
||||||
|
"type": "text_only",
|
||||||
|
"required": false,
|
||||||
|
"value": null,
|
||||||
|
"label": "<p>I’m only text</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 4,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_1",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_5",
|
||||||
|
"index": 4,
|
||||||
|
"type": "composer_preview",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>I’m a preview</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": "<p>I am prefilled</p>",
|
||||||
|
"tabindex": 5,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_1",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_1_field_6",
|
||||||
|
"index": 5,
|
||||||
|
"type": "composer_preview",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": "<p>This is the preview of the composer</p>",
|
||||||
|
"tabindex": 6,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_1",
|
||||||
|
"_validState": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_validState": 0,
|
||||||
|
"wizardId": "super_mega_fun_wizard"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2",
|
||||||
|
"index": 1,
|
||||||
|
"next": "step_3",
|
||||||
|
"previous": "step_1",
|
||||||
|
"description": "<p>Because I couldn’t think of another name for this step <img src=\"/images/emoji/twitter/slight_smile.png?v=12\" title=\":slight_smile:\" class=\"emoji\" alt=\":slight_smile:\" loading=\"lazy\" width=\"20\" height=\"20\"></p>",
|
||||||
|
"title": "Values",
|
||||||
|
"permitted": true,
|
||||||
|
"permitted_message": null,
|
||||||
|
"final": false,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "step_2_field_1",
|
||||||
|
"index": 0,
|
||||||
|
"type": "date",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Date</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": "YYYY-MM-DD",
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 1,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_2",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_2",
|
||||||
|
"index": 0,
|
||||||
|
"type": "time",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Time</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": "HH:mm",
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 2,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_2",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_3",
|
||||||
|
"index": 2,
|
||||||
|
"type": "date_time",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Date & Time</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": "",
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 3,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_2",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_4",
|
||||||
|
"index": 3,
|
||||||
|
"type": "number",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Number</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 5,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_2",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_5",
|
||||||
|
"index": 4,
|
||||||
|
"type": "checkbox",
|
||||||
|
"required": false,
|
||||||
|
"value": false,
|
||||||
|
"label": "<p>Checkbox</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 6,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_2",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_6",
|
||||||
|
"index": 5,
|
||||||
|
"type": "url",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Url</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 7,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_2",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_2_field_7",
|
||||||
|
"index": 6,
|
||||||
|
"type": "upload",
|
||||||
|
"required": false,
|
||||||
|
"value": "",
|
||||||
|
"label": "<p>Upload</p>",
|
||||||
|
"file_types": ".jpg,.jpeg,.png",
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 8,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_2",
|
||||||
|
"_validState": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_validState": 0,
|
||||||
|
"wizardId": "super_mega_fun_wizard"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3",
|
||||||
|
"index": 2,
|
||||||
|
"previous": "step_2",
|
||||||
|
"description": "<p>Unfortunately not the edible type <img src=\"/images/emoji/twitter/sushi.png?v=12\" title=\":sushi:\" class=\"emoji\" alt=\":sushi:\" loading=\"lazy\" width=\"20\" height=\"20\"></p>",
|
||||||
|
"title": "Combo-boxes",
|
||||||
|
"permitted": true,
|
||||||
|
"permitted_message": null,
|
||||||
|
"final": true,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "step_3_field_1",
|
||||||
|
"index": 0,
|
||||||
|
"type": "dropdown",
|
||||||
|
"required": false,
|
||||||
|
"value": "choice1",
|
||||||
|
"label": "<p>Custom Dropdown</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"id": "one",
|
||||||
|
"name": "One"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "two",
|
||||||
|
"name": "Two"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 1,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_3",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_2",
|
||||||
|
"index": 0,
|
||||||
|
"type": "tag",
|
||||||
|
"required": false,
|
||||||
|
"value": null,
|
||||||
|
"label": "<p>Tag</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 2,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_3",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_3",
|
||||||
|
"index": 2,
|
||||||
|
"type": "category",
|
||||||
|
"required": false,
|
||||||
|
"value": null,
|
||||||
|
"label": "<p>Category</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": 1,
|
||||||
|
"property": "id",
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 3,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_3",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_4",
|
||||||
|
"index": 3,
|
||||||
|
"type": "group",
|
||||||
|
"required": false,
|
||||||
|
"value": null,
|
||||||
|
"label": "<p>Group</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 4,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_3",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_5",
|
||||||
|
"index": 4,
|
||||||
|
"type": "user_selector",
|
||||||
|
"required": false,
|
||||||
|
"value": null,
|
||||||
|
"label": "<p>User Selector</p>",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 5,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_3",
|
||||||
|
"_validState": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "step_3_field_6",
|
||||||
|
"index": 5,
|
||||||
|
"type": "user_selector",
|
||||||
|
"required": false,
|
||||||
|
"value": null,
|
||||||
|
"label": "<p>Conditional User Selector</p>",
|
||||||
|
"description": "Shown when checkbox in step_2_field_5 is true",
|
||||||
|
"file_types": null,
|
||||||
|
"format": null,
|
||||||
|
"limit": null,
|
||||||
|
"property": null,
|
||||||
|
"content": null,
|
||||||
|
"validations": {},
|
||||||
|
"max_length": null,
|
||||||
|
"char_counter": null,
|
||||||
|
"preview_template": null,
|
||||||
|
"tabindex": 6,
|
||||||
|
"wizardId": "super_mega_fun_wizard",
|
||||||
|
"stepId": "step_3",
|
||||||
|
"_validState": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_validState": 0,
|
||||||
|
"wizardId": "super_mega_fun_wizard"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"groups": []
|
||||||
|
}
|
53
assets/javascripts/wizard/tests/helpers/acceptance.js.es6
Normale Datei
53
assets/javascripts/wizard/tests/helpers/acceptance.js.es6
Normale Datei
|
@ -0,0 +1,53 @@
|
||||||
|
import { module } from "qunit";
|
||||||
|
import setupPretender, { response } from "../pretender";
|
||||||
|
import startApp from "../helpers/start-app";
|
||||||
|
|
||||||
|
let server;
|
||||||
|
let app;
|
||||||
|
|
||||||
|
function acceptance(name, requests, cb) {
|
||||||
|
module(`Acceptance: ${name}`, function(hooks) {
|
||||||
|
hooks.beforeEach(function() {
|
||||||
|
server = setupPretender(function(pretender) {
|
||||||
|
requests.forEach(req => {
|
||||||
|
pretender[req.verb](req.path, () => (response(req.status, req.response)));
|
||||||
|
});
|
||||||
|
return pretender;
|
||||||
|
});
|
||||||
|
app = startApp();
|
||||||
|
});
|
||||||
|
|
||||||
|
hooks.afterEach(function() {
|
||||||
|
app.destroy();
|
||||||
|
server.shutdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
cb(hooks);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default acceptance;
|
||||||
|
|
||||||
|
export {
|
||||||
|
server
|
||||||
|
};
|
||||||
|
|
||||||
|
// The discourse/test/helpers/qunit-helpers file has many functions and imports
|
||||||
|
// we don't need, so there will be some duplciation here.
|
||||||
|
|
||||||
|
export function queryAll(selector, context) {
|
||||||
|
context = context || "#ember-testing";
|
||||||
|
return $(selector, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function query() {
|
||||||
|
return document.querySelector("#ember-testing").querySelector(...arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function visible(selector) {
|
||||||
|
return queryAll(selector + ":visible").length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function count(selector) {
|
||||||
|
return queryAll(selector).length;
|
||||||
|
}
|
19
assets/javascripts/wizard/tests/helpers/start-app.js.es6
Normale Datei
19
assets/javascripts/wizard/tests/helpers/start-app.js.es6
Normale Datei
|
@ -0,0 +1,19 @@
|
||||||
|
const CustomWizard = requirejs("discourse/plugins/discourse-custom-wizard/wizard/application").default;
|
||||||
|
const initializer = requirejs("discourse/plugins/discourse-custom-wizard/wizard/lib/initialize/wizard").default;
|
||||||
|
const siteSettings = requirejs("discourse/plugins/discourse-custom-wizard/wizard/tests/fixtures/site-settings").default;
|
||||||
|
const { cloneJSON } = requirejs("discourse-common/lib/object").default;
|
||||||
|
|
||||||
|
let app;
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
app = CustomWizard.create({ rootElement: "#ember-testing" });
|
||||||
|
app.start();
|
||||||
|
|
||||||
|
app.SiteSettings = cloneJSON(siteSettings);
|
||||||
|
initializer.initialize(app);
|
||||||
|
|
||||||
|
app.setupForTesting();
|
||||||
|
app.injectTestHelpers();
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
20
assets/javascripts/wizard/tests/helpers/step.js.es6
Normale Datei
20
assets/javascripts/wizard/tests/helpers/step.js.es6
Normale Datei
|
@ -0,0 +1,20 @@
|
||||||
|
import updateJson from "../fixtures/update";
|
||||||
|
import { cloneJSON } from "discourse-common/lib/object";
|
||||||
|
import wizardJson from "../fixtures/wizard";
|
||||||
|
|
||||||
|
const update = cloneJSON(updateJson);
|
||||||
|
update.wizard = cloneJSON(wizardJson);
|
||||||
|
|
||||||
|
const saveStep = function(response) {
|
||||||
|
return {
|
||||||
|
verb: "put",
|
||||||
|
path: '/w/wizard/steps/:step_id',
|
||||||
|
status: 200,
|
||||||
|
response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
saveStep,
|
||||||
|
update
|
||||||
|
}
|
7
assets/javascripts/wizard/tests/helpers/test.js.es6
Normale Datei
7
assets/javascripts/wizard/tests/helpers/test.js.es6
Normale Datei
|
@ -0,0 +1,7 @@
|
||||||
|
function exists(selector) {
|
||||||
|
return document.querySelector(selector) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
exists
|
||||||
|
}
|
52
assets/javascripts/wizard/tests/helpers/wizard.js.es6
Normale Datei
52
assets/javascripts/wizard/tests/helpers/wizard.js.es6
Normale Datei
|
@ -0,0 +1,52 @@
|
||||||
|
import wizardJson from "../fixtures/wizard";
|
||||||
|
import userJson from "../fixtures/user";
|
||||||
|
import categoriesJson from "../fixtures/categories";
|
||||||
|
import groupsJson from "../fixtures/groups";
|
||||||
|
import { cloneJSON } from "discourse-common/lib/object";
|
||||||
|
|
||||||
|
const wizardNoUser = cloneJSON(wizardJson);
|
||||||
|
const wizard = cloneJSON(wizardJson);
|
||||||
|
wizard.user = cloneJSON(userJson);
|
||||||
|
|
||||||
|
const wizardNotPermitted = cloneJSON(wizard);
|
||||||
|
wizardNotPermitted.permitted = false;
|
||||||
|
|
||||||
|
const wizardCompleted = cloneJSON(wizard);
|
||||||
|
wizardCompleted.completed = true;
|
||||||
|
|
||||||
|
wizard.start = "step_1";
|
||||||
|
wizard.resume_on_revisit = false;
|
||||||
|
wizard.submission_last_updated_at = "2022-03-11T20:00:18+01:00";
|
||||||
|
wizard.subscribed = false;
|
||||||
|
|
||||||
|
const stepNotPermitted = cloneJSON(wizard);
|
||||||
|
stepNotPermitted.steps[0].permitted = false;
|
||||||
|
|
||||||
|
const allFieldsWizard = cloneJSON(wizard);
|
||||||
|
allFieldsWizard.steps[0].fields = [
|
||||||
|
...allFieldsWizard.steps[0].fields,
|
||||||
|
...allFieldsWizard.steps[1].fields,
|
||||||
|
...allFieldsWizard.steps[2].fields
|
||||||
|
];
|
||||||
|
allFieldsWizard.steps = [cloneJSON(allFieldsWizard.steps[0])];
|
||||||
|
allFieldsWizard.categories = cloneJSON(categoriesJson['categories']);
|
||||||
|
allFieldsWizard.groups = cloneJSON(groupsJson['groups']);
|
||||||
|
|
||||||
|
const getWizard = function(response) {
|
||||||
|
return {
|
||||||
|
verb: "get",
|
||||||
|
path: "/w/wizard",
|
||||||
|
status: 200,
|
||||||
|
response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getWizard,
|
||||||
|
wizardNoUser,
|
||||||
|
wizardNotPermitted,
|
||||||
|
wizardCompleted,
|
||||||
|
stepNotPermitted,
|
||||||
|
allFieldsWizard,
|
||||||
|
wizard
|
||||||
|
}
|
|
@ -1,8 +1,4 @@
|
||||||
import Pretender from "pretender";
|
import Pretender from "pretender";
|
||||||
import WizardJson from "./fixtures/wizard";
|
|
||||||
|
|
||||||
// TODO: This file has some copied and pasted functions from `create-pretender` - would be good
|
|
||||||
// to centralize that code at some point.
|
|
||||||
|
|
||||||
function parsePostData(query) {
|
function parsePostData(query) {
|
||||||
const result = {};
|
const result = {};
|
||||||
|
@ -30,24 +26,14 @@ function response(code, obj) {
|
||||||
return [code, { "Content-Type": "application/json" }, obj];
|
return [code, { "Content-Type": "application/json" }, obj];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function () {
|
export { response };
|
||||||
const server = new Pretender(function () {
|
|
||||||
this.get("/w/wizard.json", () => {
|
|
||||||
return response(200, cloneJSON(WizardJson);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.put("/wizard/steps/:id", (request) => {
|
export default function (cb) {
|
||||||
const body = parsePostData(request.requestBody);
|
let server = new Pretender();
|
||||||
|
|
||||||
if (body.fields.full_name === "Server Fail") {
|
if (cb) {
|
||||||
return response(422, {
|
server = cb(server);
|
||||||
errors: [{ field: "full_name", description: "Invalid name" }],
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return response(200, { success: true });
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
server.prepareBody = function (body) {
|
server.prepareBody = function (body) {
|
||||||
if (body && typeof body === "object") {
|
if (body && typeof body === "object") {
|
||||||
|
@ -56,7 +42,7 @@ export default function () {
|
||||||
return body;
|
return body;
|
||||||
};
|
};
|
||||||
|
|
||||||
server.unhandledRequest = function (verb, path) {
|
server.unhandledRequest = function (verb, path, request) {
|
||||||
const error =
|
const error =
|
||||||
"Unhandled request in test environment: " + path + " (" + verb + ")";
|
"Unhandled request in test environment: " + path + " (" + verb + ")";
|
||||||
window.console.error(error);
|
window.console.error(error);
|
|
@ -46,7 +46,7 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wizard-field-composer.show-preview .d-editor-textarea-wrapper {
|
.wizard-field-composer.show-preview .d-editor-textarea-column {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
CustomWizard::Engine.routes.draw do
|
CustomWizard::Engine.routes.draw do
|
||||||
|
get 'qunit' => 'wizard#qunit'
|
||||||
get ':wizard_id' => 'wizard#index'
|
get ':wizard_id' => 'wizard#index'
|
||||||
put ':wizard_id/skip' => 'wizard#skip'
|
put ':wizard_id/skip' => 'wizard#skip'
|
||||||
get ':wizard_id/steps' => 'wizard#index'
|
get ':wizard_id/steps' => 'wizard#index'
|
||||||
|
|
|
@ -1,55 +1,40 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class CustomWizard::WizardController < ::ApplicationController
|
class CustomWizard::WizardController < ::ActionController::Base
|
||||||
include ApplicationHelper
|
helper ApplicationHelper
|
||||||
prepend_view_path(Rails.root.join('plugins', 'discourse-custom-wizard', 'views'))
|
|
||||||
layout 'wizard'
|
|
||||||
|
|
||||||
|
include CurrentUser
|
||||||
|
include CanonicalURL::ControllerExtensions
|
||||||
|
include GlobalPath
|
||||||
|
|
||||||
|
prepend_view_path(Rails.root.join('plugins', 'discourse-custom-wizard', 'views'))
|
||||||
|
layout :set_wizard_layout
|
||||||
|
|
||||||
|
before_action :preload_wizard_json
|
||||||
before_action :ensure_plugin_enabled
|
before_action :ensure_plugin_enabled
|
||||||
before_action :update_subscription, only: [:index]
|
before_action :update_subscription, only: [:index]
|
||||||
before_action :ensure_logged_in, only: [:skip]
|
before_action :ensure_logged_in, only: [:skip]
|
||||||
|
|
||||||
helper_method :wizard_page_title
|
helper_method :wizard_page_title
|
||||||
helper_method :wizard_theme_id
|
helper_method :wizard_theme_id
|
||||||
helper_method :wizard_theme_lookup
|
helper_method :wizard_theme_lookup
|
||||||
helper_method :wizard_theme_translations_lookup
|
helper_method :wizard_theme_translations_lookup
|
||||||
|
|
||||||
def wizard
|
def set_wizard_layout
|
||||||
@builder = CustomWizard::Builder.new(params[:wizard_id].underscore, current_user)
|
action_name === 'qunit' ? 'qunit' : 'wizard'
|
||||||
@wizard ||= @builder.build
|
|
||||||
@wizard
|
|
||||||
end
|
|
||||||
|
|
||||||
def wizard_page_title
|
|
||||||
wizard ? (wizard.name || wizard.id) : I18n.t('wizard.custom_title')
|
|
||||||
end
|
|
||||||
|
|
||||||
def wizard_theme_id
|
|
||||||
wizard ? wizard.theme_id : nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def wizard_theme_lookup(name)
|
|
||||||
Theme.lookup_field(wizard_theme_id, mobile_view? ? :mobile : :desktop, name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def wizard_theme_translations_lookup
|
|
||||||
Theme.lookup_field(wizard_theme_id, :translations, I18n.locale)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
builder = CustomWizard::Builder.new(params[:wizard_id].underscore, current_user)
|
if wizard.present?
|
||||||
|
render json: CustomWizard::WizardSerializer.new(wizard, scope: guardian, root: false).as_json, status: 200
|
||||||
if builder.wizard.present?
|
|
||||||
builder_opts = {}
|
|
||||||
builder_opts[:reset] = params[:reset]
|
|
||||||
built_wizard = builder.build(builder_opts, params)
|
|
||||||
|
|
||||||
render_serialized(built_wizard, ::CustomWizard::WizardSerializer, root: false)
|
|
||||||
else
|
else
|
||||||
render json: { error: I18n.t('wizard.none') }
|
render json: { error: I18n.t('wizard.none') }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
format.html {}
|
format.html do
|
||||||
|
render "default/empty"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,9 +46,8 @@ class CustomWizard::WizardController < ::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
result = success_json
|
result = success_json
|
||||||
user = current_user
|
|
||||||
|
|
||||||
if user && wizard.can_access?
|
if current_user && wizard.can_access?
|
||||||
submission = wizard.current_submission
|
submission = wizard.current_submission
|
||||||
|
|
||||||
if submission.present? && submission.redirect_to
|
if submission.present? && submission.redirect_to
|
||||||
|
@ -77,6 +61,64 @@ class CustomWizard::WizardController < ::ApplicationController
|
||||||
render json: result
|
render json: result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def qunit
|
||||||
|
raise Discourse::InvalidAccess.new if Rails.env.production?
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
render "default/empty"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def ensure_logged_in
|
||||||
|
raise Discourse::NotLoggedIn.new unless current_user.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def guardian
|
||||||
|
@guardian ||= Guardian.new(current_user, request)
|
||||||
|
end
|
||||||
|
|
||||||
|
def wizard
|
||||||
|
@wizard ||= begin
|
||||||
|
builder = CustomWizard::Builder.new(params[:wizard_id].underscore, current_user)
|
||||||
|
return nil unless builder.present?
|
||||||
|
opts = {}
|
||||||
|
opts[:reset] = params[:reset]
|
||||||
|
builder.build(opts, params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wizard_page_title
|
||||||
|
wizard ? (wizard.name || wizard.id) : I18n.t('wizard.custom_title')
|
||||||
|
end
|
||||||
|
|
||||||
|
def wizard_theme_id
|
||||||
|
wizard ? wizard.theme_id : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def wizard_theme_lookup(name)
|
||||||
|
Theme.lookup_field(wizard_theme_id, view_context.mobile_view? ? :mobile : :desktop, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def wizard_theme_translations_lookup
|
||||||
|
Theme.lookup_field(wizard_theme_id, :translations, I18n.locale)
|
||||||
|
end
|
||||||
|
|
||||||
|
def preload_wizard_json
|
||||||
|
return if request.xhr? || request.format.json?
|
||||||
|
return if request.method != "GET"
|
||||||
|
|
||||||
|
store_preloaded("siteSettings", SiteSetting.client_settings_json)
|
||||||
|
end
|
||||||
|
|
||||||
|
def store_preloaded(key, json)
|
||||||
|
@preloaded ||= {}
|
||||||
|
@preloaded[key] = json.gsub("</", "<\\/")
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def ensure_plugin_enabled
|
def ensure_plugin_enabled
|
||||||
|
|
|
@ -6,6 +6,7 @@ module ExtraLocalesControllerCustomWizard
|
||||||
path = URI(request.referer).path
|
path = URI(request.referer).path
|
||||||
wizard_path = path.split('/w/').last
|
wizard_path = path.split('/w/').last
|
||||||
wizard_id = wizard_path.split('/').first
|
wizard_id = wizard_path.split('/').first
|
||||||
|
return true if wizard_id == "qunit"
|
||||||
CustomWizard::Template.exists?(wizard_id.underscore)
|
CustomWizard::Template.exists?(wizard_id.underscore)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ::CustomWizard::UpdateValidator
|
||||||
field_id = field.id.to_s
|
field_id = field.id.to_s
|
||||||
value = @updater.submission[field_id]
|
value = @updater.submission[field_id]
|
||||||
min_length = false
|
min_length = false
|
||||||
label = field.raw[:label] || I18n.t("#{field.key}.label")
|
label = field.raw[:label]
|
||||||
type = field.type
|
type = field.type
|
||||||
required = field.required
|
required = field.required
|
||||||
min_length = field.min_length if is_text_type(field)
|
min_length = field.min_length if is_text_type(field)
|
||||||
|
|
|
@ -18,9 +18,8 @@ config.assets.paths << "#{plugin_asset_path}/stylesheets/wizard"
|
||||||
if Rails.env.production?
|
if Rails.env.production?
|
||||||
config.assets.precompile += %w{
|
config.assets.precompile += %w{
|
||||||
wizard-custom-guest.js
|
wizard-custom-guest.js
|
||||||
wizard-custom-globals.js
|
|
||||||
wizard-custom.js
|
|
||||||
wizard-custom-start.js
|
wizard-custom-start.js
|
||||||
|
wizard-custom.js
|
||||||
wizard-plugin.js.erb
|
wizard-plugin.js.erb
|
||||||
wizard-raw-templates.js.erb
|
wizard-raw-templates.js.erb
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import { click, currentRouteName, fillIn, visit } from "@ember/test-helpers";
|
|
||||||
import { module, test } from "qunit";
|
|
||||||
import { run } from "@ember/runloop";
|
|
||||||
import startApp from "../helpers/start-app";
|
|
||||||
console.log("STARTING TEST");
|
|
||||||
let wizard;
|
|
||||||
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
|
||||||
console.log(error);
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
module("Acceptance: Custom Wizard", {
|
|
||||||
beforeEach() {
|
|
||||||
console.log("BEFORE EACH")
|
|
||||||
wizard = startApp();
|
|
||||||
},
|
|
||||||
|
|
||||||
afterEach() {
|
|
||||||
run(wizard, "destroy");
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
function exists(selector) {
|
|
||||||
return document.querySelector(selector) !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Wizard starts", async function (assert) {
|
|
||||||
console.log("TEST")
|
|
||||||
await visit("/w/wizard");
|
|
||||||
assert.ok(exists(".wizard-column"));
|
|
||||||
});
|
|
|
@ -1,340 +0,0 @@
|
||||||
export default {
|
|
||||||
"id": "super_mega_fun_wizard",
|
|
||||||
"name": "Super Mega Fun Wizard",
|
|
||||||
"background": "#333333",
|
|
||||||
"save_submissions": true,
|
|
||||||
"after_signup": false,
|
|
||||||
"prompt_completion": false,
|
|
||||||
"theme_id": 2,
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"id": "step_1",
|
|
||||||
"title": "Text",
|
|
||||||
"raw_description": "Text inputs!",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"id": "step_1_field_1",
|
|
||||||
"label": "Text",
|
|
||||||
"description": "Text field description.",
|
|
||||||
"type": "text",
|
|
||||||
"min_length": "3",
|
|
||||||
"prefill": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "I am prefilled",
|
|
||||||
"output_type": "text",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_1_field_2",
|
|
||||||
"label": "Textarea",
|
|
||||||
"type": "textarea",
|
|
||||||
"min_length": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_1_field_3",
|
|
||||||
"label": "Composer",
|
|
||||||
"type": "composer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_1_field_4",
|
|
||||||
"label": "I'm only text",
|
|
||||||
"description": "",
|
|
||||||
"type": "text_only"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Text inputs!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_2",
|
|
||||||
"title": "Values",
|
|
||||||
"raw_description": "Because I couldn't think of another name for this step :)",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"id": "step_2_field_1",
|
|
||||||
"label": "Date",
|
|
||||||
"type": "date",
|
|
||||||
"format": "YYYY-MM-DD"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_2_field_2",
|
|
||||||
"label": "Time",
|
|
||||||
"type": "time",
|
|
||||||
"format": "HH:mm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_2_field_3",
|
|
||||||
"label": "Date & Time",
|
|
||||||
"type": "date_time",
|
|
||||||
"format": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_2_field_4",
|
|
||||||
"label": "Number",
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_2_field_5",
|
|
||||||
"label": "Checkbox",
|
|
||||||
"type": "checkbox"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_2_field_6",
|
|
||||||
"label": "Url",
|
|
||||||
"type": "url"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_2_field_7",
|
|
||||||
"label": "Upload",
|
|
||||||
"type": "upload",
|
|
||||||
"file_types": ".jpg,.jpeg,.png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Because I couldn't think of another name for this step :)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3",
|
|
||||||
"title": "Combo-boxes",
|
|
||||||
"raw_description": "Unfortunately not the edible type :sushi: ",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"id": "step_3_field_1",
|
|
||||||
"label": "Custom Dropdown",
|
|
||||||
"type": "dropdown",
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"type": "association",
|
|
||||||
"pairs": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"key": "choice1",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Choice 1",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "equal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 1,
|
|
||||||
"key": "choice2",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Choice 2",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 2,
|
|
||||||
"key": "choice3",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Choice 3",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_2",
|
|
||||||
"label": "Tag",
|
|
||||||
"type": "tag"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_3",
|
|
||||||
"label": "Category",
|
|
||||||
"type": "category",
|
|
||||||
"limit": 1,
|
|
||||||
"property": "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_4",
|
|
||||||
"label": "Group",
|
|
||||||
"type": "group"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_5",
|
|
||||||
"label": "User Selector",
|
|
||||||
"description": "",
|
|
||||||
"type": "user_selector"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step_3_field_6",
|
|
||||||
"label": "Conditional User Selector",
|
|
||||||
"description": "Shown when checkbox in step_2_field_5 is true",
|
|
||||||
"type": "user_selector"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Unfortunately not the edible type :sushi: "
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"id": "action_1",
|
|
||||||
"run_after": "step_3",
|
|
||||||
"type": "create_topic",
|
|
||||||
"skip_redirect": true,
|
|
||||||
"post": "step_1_field_2",
|
|
||||||
"title": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "step_1_field_1",
|
|
||||||
"output_type": "wizard_field",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"category": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "step_3_field_3",
|
|
||||||
"output_type": "wizard_field",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "step_3_field_2",
|
|
||||||
"output_type": "wizard_field",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"custom_fields": [
|
|
||||||
{
|
|
||||||
"type": "association",
|
|
||||||
"pairs": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"key": "post_field",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Post custom field value",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 1,
|
|
||||||
"key": "topic.topic_field",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Topic custom field value",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 2,
|
|
||||||
"key": "topic.topic_json_field{}.key_1",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Key 1 value",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"index": 3,
|
|
||||||
"key": "topic.topic_json_field{}.key_2",
|
|
||||||
"key_type": "text",
|
|
||||||
"value": "Key 2 value",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "association"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"visible": [
|
|
||||||
{
|
|
||||||
"type": "conditional",
|
|
||||||
"output": "true",
|
|
||||||
"output_type": "text",
|
|
||||||
"output_connector": "then",
|
|
||||||
"pairs": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"key": "name",
|
|
||||||
"key_type": "user_field",
|
|
||||||
"value": "Angus",
|
|
||||||
"value_type": "text",
|
|
||||||
"connector": "equal"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "action_5",
|
|
||||||
"run_after": "step_1",
|
|
||||||
"type": "watch_categories",
|
|
||||||
"notification_level": "tracking",
|
|
||||||
"wizard_user": true,
|
|
||||||
"categories": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "action_8",
|
|
||||||
"output_type": "wizard_action",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mute_remainder": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "true",
|
|
||||||
"output_type": "text",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "action_4",
|
|
||||||
"run_after": "step_2",
|
|
||||||
"type": "update_profile",
|
|
||||||
"profile_updates": [
|
|
||||||
{
|
|
||||||
"type": "association",
|
|
||||||
"pairs": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"key": "profile_background",
|
|
||||||
"key_type": "user_field",
|
|
||||||
"value": "step_2_field_7",
|
|
||||||
"value_type": "wizard_field",
|
|
||||||
"connector": "association"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "action_3",
|
|
||||||
"run_after": "step_2",
|
|
||||||
"type": "open_composer",
|
|
||||||
"post_builder": true,
|
|
||||||
"post_template": "I am interpolating some user fields u{name} u{username} u{email}",
|
|
||||||
"title": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "Title of the composer topic",
|
|
||||||
"output_type": "text",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "tag1",
|
|
||||||
"output_type": "text",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "action_10",
|
|
||||||
"run_after": "step_3",
|
|
||||||
"type": "route_to",
|
|
||||||
"url": [
|
|
||||||
{
|
|
||||||
"type": "assignment",
|
|
||||||
"output": "https://google.com",
|
|
||||||
"output_type": "text",
|
|
||||||
"output_connector": "set"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
import CustomWizard from "discourse/plugins/discourse-custom-wizard/wizard/custom-wizard";
|
|
||||||
import wizardInitializer from "discourse/plugins/discourse-custom-wizard/wizard/initializers/custom-wizard";
|
|
||||||
import stepInitializer from "discourse/plugins/discourse-custom-wizard/wizard/initializers/custom-wizard-step";
|
|
||||||
import fieldInitializer from "discourse/plugins/discourse-custom-wizard/wizard/initializers/custom-wizard-field";
|
|
||||||
import { run } from "@ember/runloop";
|
|
||||||
|
|
||||||
let app;
|
|
||||||
let started = false;
|
|
||||||
|
|
||||||
export default function () {
|
|
||||||
run(() => (app = CustomWizard.create({ rootElement: "#ember-testing" })));
|
|
||||||
|
|
||||||
if (!started) {
|
|
||||||
wizardInitializer.initialize(app);
|
|
||||||
stepInitializer.initialize(app);
|
|
||||||
fieldInitializer.initialize(app);
|
|
||||||
app.start();
|
|
||||||
started = true;
|
|
||||||
}
|
|
||||||
app.setupForTesting();
|
|
||||||
app.injectTestHelpers();
|
|
||||||
return app;
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
// discourse-skip-module
|
|
||||||
/*global document, Logster, QUnit */
|
|
||||||
console.log('starting test_helper')
|
|
||||||
window.Discourse = {};
|
|
||||||
window.Wizard = {};
|
|
||||||
Wizard.SiteSettings = {};
|
|
||||||
Discourse.__widget_helpers = {};
|
|
||||||
Discourse.SiteSettings = Wizard.SiteSettings;
|
|
||||||
|
|
||||||
//= require env
|
|
||||||
//= require jquery.debug
|
|
||||||
//= require ember.debug
|
|
||||||
//= require locales/i18n
|
|
||||||
//= require locales/en
|
|
||||||
//= require route-recognizer
|
|
||||||
//= require fake_xml_http_request
|
|
||||||
//= require pretender
|
|
||||||
//= require qunit
|
|
||||||
//= require ember-qunit
|
|
||||||
//= require discourse-loader
|
|
||||||
//= require jquery.debug
|
|
||||||
//= require handlebars
|
|
||||||
//= require ember-template-compiler
|
|
||||||
//= require wizard-custom
|
|
||||||
//= require wizard-vendor
|
|
||||||
//= require_tree ./helpers
|
|
||||||
//= require_tree ./acceptance
|
|
||||||
//= require_tree ./models
|
|
||||||
//= require_tree ./components
|
|
||||||
//= require ./wizard-pretender
|
|
||||||
//= require test-shims
|
|
||||||
console.log ("end of require")
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
|
||||||
document.body.insertAdjacentHTML(
|
|
||||||
"afterbegin",
|
|
||||||
`
|
|
||||||
<div id="ember-testing-container"><div id="ember-testing"></div></div>
|
|
||||||
<style>#ember-testing-container { position: absolute; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; } #ember-testing { zoom: 50%; }</style>
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (window.Logster) {
|
|
||||||
Logster.enabled = false;
|
|
||||||
} else {
|
|
||||||
window.Logster = { enabled: false };
|
|
||||||
}
|
|
||||||
Ember.Test.adapter = window.QUnitAdapter.create();
|
|
||||||
|
|
||||||
/*let createPretendServer = requirejs("./wizard-pretender", null, null, false).default;
|
|
||||||
|
|
||||||
let server;
|
|
||||||
QUnit.testStart(function () {
|
|
||||||
server = createPretendServer();
|
|
||||||
});
|
|
||||||
|
|
||||||
QUnit.testDone(function () {
|
|
||||||
server.shutdown();
|
|
||||||
});*/
|
|
||||||
|
|
||||||
let _testApp = requirejs("./helpers/start-app").default();
|
|
||||||
let _buildResolver = requirejs("discourse-common/resolver").buildResolver;
|
|
||||||
window.setResolver(_buildResolver("wizard").create({ namespace: _testApp }));
|
|
||||||
|
|
||||||
Object.keys(requirejs.entries).forEach(function (entry) {
|
|
||||||
if (/\-test/.test(entry)) {
|
|
||||||
requirejs(entry, null, null, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log ("end of helper")
|
|
28
views/layouts/qunit.html.erb
Normale Datei
28
views/layouts/qunit.html.erb
Normale Datei
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Custom Wizard QUnit Test Runner</title>
|
||||||
|
<%= discourse_stylesheet_link_tag(:test_helper, theme_id: nil) %>
|
||||||
|
<%= discourse_stylesheet_link_tag :wizard, theme_id: nil %>
|
||||||
|
<%= discourse_stylesheet_link_tag :wizard_custom %>
|
||||||
|
<%= preload_script "locales/en" %>
|
||||||
|
<%= preload_script "ember_jquery" %>
|
||||||
|
<%= preload_script "wizard-vendor" %>
|
||||||
|
<%= preload_script "wizard-custom" %>
|
||||||
|
<%= preload_script "wizard-raw-templates" %>
|
||||||
|
<%= preload_script "wizard-plugin" %>
|
||||||
|
<%= preload_script "pretty-text-bundle" %>
|
||||||
|
<%= preload_script "wizard-qunit" %>
|
||||||
|
<%= csrf_meta_tags %>
|
||||||
|
|
||||||
|
<script src="<%= ExtraLocalesController.url("wizard") %>"></script>
|
||||||
|
|
||||||
|
<%= tag.meta id: 'data-discourse-setup', data: client_side_setup_data %>
|
||||||
|
<meta name="discourse_theme_id" content="">
|
||||||
|
<meta name="discourse-base-uri" content="<%= Discourse.base_path %>">
|
||||||
|
</head>
|
||||||
|
<body class="custom-wizard">
|
||||||
|
<div id="qunit"></div>
|
||||||
|
<div id="qunit-fixture"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -11,10 +11,8 @@
|
||||||
<%= preload_script "locales/#{I18n.locale}" %>
|
<%= preload_script "locales/#{I18n.locale}" %>
|
||||||
<%= preload_script "ember_jquery" %>
|
<%= preload_script "ember_jquery" %>
|
||||||
<%= preload_script "wizard-vendor" %>
|
<%= preload_script "wizard-vendor" %>
|
||||||
<%= preload_script "wizard-application" %>
|
|
||||||
<%= preload_script "wizard-custom-globals" %>
|
|
||||||
<%= preload_script "wizard-raw-templates" %>
|
|
||||||
<%= preload_script "wizard-custom" %>
|
<%= preload_script "wizard-custom" %>
|
||||||
|
<%= preload_script "wizard-raw-templates" %>
|
||||||
<%= preload_script "wizard-plugin" %>
|
<%= preload_script "wizard-plugin" %>
|
||||||
<%= preload_script "pretty-text-bundle" %>
|
<%= preload_script "pretty-text-bundle" %>
|
||||||
<script src="<%= ExtraLocalesController.url("wizard") %>"></script>
|
<script src="<%= ExtraLocalesController.url("wizard") %>"></script>
|
||||||
|
@ -58,5 +56,7 @@
|
||||||
<%= raw SvgSprite.bundle %>
|
<%= raw SvgSprite.bundle %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="hidden" id="data-preloaded-wizard" data-preloaded-wizard="<%= preloaded_json %>"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Laden …
In neuem Issue referenzieren