Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-26 02:50:28 +01:00
Upload files, drag and drop files, syntax highlighting working
Dieser Commit ist enthalten in:
Ursprung
3fd3900cea
Commit
67d87f74c1
7 geänderte Dateien mit 271 neuen und 168 gelöschten Zeilen
|
@ -38,6 +38,7 @@
|
|||
//= require discourse/app/lib/cookie
|
||||
//= require discourse/app/lib/public-js-versions
|
||||
//= require discourse/app/lib/load-oneboxes
|
||||
//= require discourse/app/lib/highlight-syntax
|
||||
|
||||
//= require discourse/app/mixins/singleton
|
||||
//= require discourse/app/mixins/upload
|
||||
|
@ -128,6 +129,7 @@
|
|||
//= require template_include.js
|
||||
//= require caret_position.js
|
||||
//= require popper.js
|
||||
//= require bootstrap-modal.js
|
||||
//= require bootbox.js
|
||||
//= require discourse-shims
|
||||
|
||||
|
|
|
@ -1,37 +1,41 @@
|
|||
import ComposerEditor from 'discourse/components/composer-editor';
|
||||
import { default as computed, on } from 'discourse-common/utils/decorators';
|
||||
import ComposerEditor from "discourse/components/composer-editor";
|
||||
import { default as computed, on } from "discourse-common/utils/decorators";
|
||||
import { findRawTemplate } from "discourse-common/lib/raw-templates";
|
||||
import { throttle } from "@ember/runloop";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
import { safariHacksDisabled } from "discourse/lib/utilities";
|
||||
import highlightSyntax from "discourse/lib/highlight-syntax";
|
||||
import { getToken } from "wizard/lib/ajax";
|
||||
import { validateUploadedFiles } from "discourse/lib/uploads";
|
||||
|
||||
const uploadHandlers = [];
|
||||
export default ComposerEditor.extend({
|
||||
classNameBindings: ['fieldClass'],
|
||||
allowUpload: false,
|
||||
classNameBindings: ["fieldClass"],
|
||||
allowUpload: true,
|
||||
showLink: false,
|
||||
topic: null,
|
||||
showToolbar: true,
|
||||
focusTarget: "reply",
|
||||
canWhisper: false,
|
||||
lastValidatedAt: 'lastValidatedAt',
|
||||
lastValidatedAt: "lastValidatedAt",
|
||||
uploadIcon: "upload",
|
||||
popupMenuOptions: [],
|
||||
draftStatus: 'null',
|
||||
|
||||
draftStatus: "null",
|
||||
|
||||
@on("didInsertElement")
|
||||
_composerEditorInit() {
|
||||
const $input = $(this.element.querySelector(".d-editor-input"));
|
||||
const $preview = $(this.element.querySelector(".d-editor-preview-wrapper"));
|
||||
|
||||
|
||||
if (this.siteSettings.enable_mentions) {
|
||||
$input.autocomplete({
|
||||
template: findRawTemplate("user-selector-autocomplete"),
|
||||
dataSource: term => this.userSearchTerm.call(this, term),
|
||||
dataSource: (term) => this.userSearchTerm.call(this, term),
|
||||
key: "@",
|
||||
transformComplete: v => v.username || v.name,
|
||||
transformComplete: (v) => v.username || v.name,
|
||||
afterComplete() {
|
||||
scheduleOnce("afterRender", () => $input.blur().focus());
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -45,13 +49,73 @@ export default ComposerEditor.extend({
|
|||
|
||||
this._bindUploadTarget();
|
||||
},
|
||||
|
||||
|
||||
showUploadModal() {
|
||||
$(".wizard-composer-upload").trigger("click");
|
||||
},
|
||||
_setUploadPlaceholderSend() {
|
||||
if (!this.composer.get("reply")) {
|
||||
this.composer.set("reply", "");
|
||||
}
|
||||
this._super(...arguments);
|
||||
},
|
||||
|
||||
_bindUploadTarget() {
|
||||
this._super(...arguments);
|
||||
const $element = $(this.element);
|
||||
$element.off("fileuploadsubmit");
|
||||
$element.on("fileuploadsubmit", (e, data) => {
|
||||
const max = this.siteSettings.simultaneous_uploads;
|
||||
|
||||
// Limit the number of simultaneous uploads
|
||||
if (max > 0 && data.files.length > max) {
|
||||
bootbox.alert(
|
||||
I18n.t("post.errors.too_many_dragged_and_dropped_files", { max })
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Look for a matching file upload handler contributed from a plugin
|
||||
const matcher = (handler) => {
|
||||
const ext = handler.extensions.join("|");
|
||||
const regex = new RegExp(`\\.(${ext})$`, "i");
|
||||
return regex.test(data.files[0].name);
|
||||
};
|
||||
|
||||
const matchingHandler = uploadHandlers.find(matcher);
|
||||
if (data.files.length === 1 && matchingHandler) {
|
||||
if (!matchingHandler.method(data.files[0], this)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If no plugin, continue as normal
|
||||
const isPrivateMessage = this.get("composer.privateMessage");
|
||||
|
||||
data.formData = { type: "composer" };
|
||||
data.formData.authenticity_token = getToken();
|
||||
if (isPrivateMessage) {
|
||||
data.formData.for_private_message = true;
|
||||
}
|
||||
if (this._pasted) {
|
||||
data.formData.pasted = true;
|
||||
}
|
||||
|
||||
const opts = {
|
||||
user: this.currentUser,
|
||||
siteSettings: this.siteSettings,
|
||||
isPrivateMessage,
|
||||
allowStaffToUploadAnyFileInPm: this.siteSettings
|
||||
.allow_staff_to_upload_any_file_in_pm,
|
||||
};
|
||||
|
||||
const isUploading = validateUploadedFiles(data.files, opts);
|
||||
|
||||
this.setProperties({ uploadProgress: 0, isUploading });
|
||||
|
||||
return isUploading;
|
||||
});
|
||||
},
|
||||
|
||||
_unbindUploadTarget() {
|
||||
},
|
||||
|
||||
actions: {
|
||||
extraButtons(toolbar) {
|
||||
if (this.allowUpload && this.uploadIcon && !this.site.mobileView) {
|
||||
|
@ -60,9 +124,13 @@ export default ComposerEditor.extend({
|
|||
group: "insertions",
|
||||
icon: this.uploadIcon,
|
||||
title: "upload",
|
||||
sendAction: this.showUploadModal
|
||||
sendAction: this.showUploadModal,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
previewUpdated($preview) {
|
||||
highlightSyntax($preview[0], this.siteSettings, this.session);
|
||||
this._super(...arguments);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,34 +1,45 @@
|
|||
import { default as computed } from 'discourse-common/utils/decorators';
|
||||
import { default as computed } from "discourse-common/utils/decorators";
|
||||
import { dasherize } from "@ember/string";
|
||||
|
||||
export default {
|
||||
name: 'custom-routes',
|
||||
|
||||
name: "custom-routes",
|
||||
after: "sniff-capabilities",
|
||||
initialize(app) {
|
||||
if (window.location.pathname.indexOf('/w/') < 0) return;
|
||||
if (window.location.pathname.indexOf("/w/") < 0) return;
|
||||
|
||||
const EmberObject = requirejs('@ember/object').default;
|
||||
const Router = requirejs('wizard/router').default;
|
||||
const ApplicationRoute = requirejs('wizard/routes/application').default;
|
||||
const ajax = requirejs('wizard/lib/ajax').ajax;
|
||||
const StepModel = requirejs('wizard/models/step').default;
|
||||
const CustomWizard = requirejs('discourse/plugins/discourse-custom-wizard/wizard/models/custom').default;
|
||||
const WizardStep = requirejs('wizard/components/wizard-step').default;
|
||||
const WizardField = requirejs('wizard/components/wizard-field').default;
|
||||
const getUrl = requirejs('discourse-common/lib/get-url').default;
|
||||
const FieldModel = requirejs('wizard/models/wizard-field').default;
|
||||
const autocomplete = requirejs('discourse/lib/autocomplete').default;
|
||||
const cook = requirejs('discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite').cook;
|
||||
const EmberObject = requirejs("@ember/object").default;
|
||||
const Router = requirejs("wizard/router").default;
|
||||
const ApplicationRoute = requirejs("wizard/routes/application").default;
|
||||
const ajax = requirejs("wizard/lib/ajax").ajax;
|
||||
const StepModel = requirejs("wizard/models/step").default;
|
||||
const CustomWizard = requirejs(
|
||||
"discourse/plugins/discourse-custom-wizard/wizard/models/custom"
|
||||
).default;
|
||||
const WizardStep = requirejs("wizard/components/wizard-step").default;
|
||||
const WizardField = requirejs("wizard/components/wizard-field").default;
|
||||
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
||||
const FieldModel = requirejs("wizard/models/wizard-field").default;
|
||||
const autocomplete = requirejs("discourse/lib/autocomplete").default;
|
||||
const cook = requirejs(
|
||||
"discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite"
|
||||
).cook;
|
||||
const Singleton = requirejs("discourse/mixins/singleton").default;
|
||||
const Store = requirejs("discourse/models/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 Site = requirejs("discourse/plugins/discourse-custom-wizard/wizard/models/site").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 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 setDefaultOwner = requirejs("discourse-common/lib/get-owner")
|
||||
.setDefaultOwner;
|
||||
const messageBus = requirejs("message-bus-client").default;
|
||||
const container = app.__container__;
|
||||
Discourse.Model = EmberObject.extend();
|
||||
Discourse.__container__ = container;
|
||||
|
@ -37,20 +48,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 ){
|
||||
var ownProps = Object.keys( obj ),
|
||||
i = ownProps.length,
|
||||
resArray = new Array(i); // preallocate the Array
|
||||
while (i--)
|
||||
resArray[i] = [ownProps[i], obj[ownProps[i]]];
|
||||
Object.entries = function (obj) {
|
||||
var 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;
|
||||
};
|
||||
|
||||
$.fn.autocomplete = autocomplete;
|
||||
|
||||
Object.keys(Ember.TEMPLATES).forEach(k => {
|
||||
if (k.indexOf("select-kit") === 0) {
|
||||
|
||||
Object.keys(Ember.TEMPLATES).forEach((k) => {
|
||||
if (k.indexOf("select-kit") === 0) {
|
||||
let template = Ember.TEMPLATES[k];
|
||||
define(k, () => template);
|
||||
}
|
||||
|
@ -61,148 +71,162 @@ export default {
|
|||
const siteSettings = Wizard.SiteSettings;
|
||||
app.register("site-settings:main", siteSettings, { instantiate: false });
|
||||
createHelperContext({ siteSettings });
|
||||
targets.forEach(t => app.inject(t, "siteSettings", "site-settings:main"));
|
||||
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"));
|
||||
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"));
|
||||
|
||||
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);
|
||||
|
||||
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"));
|
||||
let context = {
|
||||
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"),
|
||||
};
|
||||
createHelperContext(context);
|
||||
|
||||
const session = container.lookup("session:main");
|
||||
const setupData = document.getElementById("data-discourse-setup").dataset;
|
||||
session.set("highlightJsPath", setupData.highlightJsPath);
|
||||
Router.reopen({
|
||||
rootURL: getUrl('/w/')
|
||||
rootURL: getUrl("/w/"),
|
||||
});
|
||||
|
||||
Router.map(function() {
|
||||
this.route('custom', { path: '/:wizard_id' }, function() {
|
||||
this.route('steps');
|
||||
this.route('step', { path: '/steps/:step_id' });
|
||||
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');
|
||||
this.transitionTo("custom");
|
||||
},
|
||||
|
||||
model() {}
|
||||
model() {},
|
||||
});
|
||||
|
||||
WizardStep.reopen({
|
||||
classNameBindings: ['step.id'],
|
||||
classNameBindings: ["step.id"],
|
||||
|
||||
animateInvalidFields() {
|
||||
Ember.run.scheduleOnce('afterRender', () => {
|
||||
let $element = $('.invalid input[type=text], .invalid textarea, .invalid input[type=checkbox], .invalid .select-kit');
|
||||
|
||||
Ember.run.scheduleOnce("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);
|
||||
});
|
||||
$([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'),
|
||||
ensureStartsAtTop: function () {
|
||||
window.scrollTo(0, 0);
|
||||
}.observes("step.id"),
|
||||
|
||||
showQuitButton: function() {
|
||||
const index = this.get('step.index');
|
||||
const required = this.get('wizard.required');
|
||||
showQuitButton: function () {
|
||||
const index = this.get("step.index");
|
||||
const required = this.get("wizard.required");
|
||||
return index === 0 && !required;
|
||||
}.property('step.index', 'wizard.required'),
|
||||
}.property("step.index", "wizard.required"),
|
||||
|
||||
cookedTitle: function() {
|
||||
return cook(this.get('step.title'));
|
||||
}.property('step.title'),
|
||||
cookedTitle: function () {
|
||||
return cook(this.get("step.title"));
|
||||
}.property("step.title"),
|
||||
|
||||
cookedDescription: function() {
|
||||
return cook(this.get('step.description'));
|
||||
}.property('step.description'),
|
||||
cookedDescription: function () {
|
||||
return cook(this.get("step.description"));
|
||||
}.property("step.description"),
|
||||
|
||||
bannerImage: function() {
|
||||
const src = this.get('step.banner');
|
||||
bannerImage: function () {
|
||||
const src = this.get("step.banner");
|
||||
if (!src) return;
|
||||
return getUrl(src);
|
||||
}.property('step.banner'),
|
||||
}.property("step.banner"),
|
||||
|
||||
handleMessage: function() {
|
||||
const message = this.get('step.message');
|
||||
this.sendAction('showMessage', message);
|
||||
}.observes('step.message'),
|
||||
handleMessage: function () {
|
||||
const message = this.get("step.message");
|
||||
this.sendAction("showMessage", message);
|
||||
}.observes("step.message"),
|
||||
|
||||
advance() {
|
||||
this.set('saving', true);
|
||||
this.get('step').save()
|
||||
.then(response => {
|
||||
if (this.get('finalStep')) {
|
||||
this.set("saving", true);
|
||||
this.get("step")
|
||||
.save()
|
||||
.then((response) => {
|
||||
if (this.get("finalStep")) {
|
||||
CustomWizard.finished(response);
|
||||
} else {
|
||||
this.sendAction('goNext', response);
|
||||
this.sendAction("goNext", response);
|
||||
}
|
||||
})
|
||||
.catch(() => this.animateInvalidFields())
|
||||
.finally(() => this.set('saving', false));
|
||||
},
|
||||
|
||||
keyPress(key) {
|
||||
.finally(() => this.set("saving", false));
|
||||
},
|
||||
|
||||
keyPress(key) {},
|
||||
|
||||
actions: {
|
||||
quit() {
|
||||
this.get('wizard').skip();
|
||||
this.get("wizard").skip();
|
||||
},
|
||||
|
||||
done() {
|
||||
this.set('finalStep', true);
|
||||
this.send('nextStep');
|
||||
this.set("finalStep", true);
|
||||
this.send("nextStep");
|
||||
},
|
||||
|
||||
showMessage(message) {
|
||||
this.sendAction('showMessage', message);
|
||||
}
|
||||
}
|
||||
this.sendAction("showMessage", message);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
StepModel.reopen({
|
||||
save() {
|
||||
const wizardId = this.get('wizardId');
|
||||
const wizardId = this.get("wizardId");
|
||||
const fields = {};
|
||||
|
||||
this.get('fields').forEach(f => {
|
||||
if (f.type !== 'text_only') {
|
||||
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) {
|
||||
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 => {
|
||||
response.responseJSON.errors.forEach((err) => {
|
||||
if (err.field === wizardId) {
|
||||
wizardErrors.push(err.description);
|
||||
} else if (err.field) {
|
||||
|
@ -212,7 +236,7 @@ export default {
|
|||
}
|
||||
});
|
||||
if (wizardErrors.length) {
|
||||
this.handleWizardError(wizardErrors.join('\n'));
|
||||
this.handleWizardError(wizardErrors.join("\n"));
|
||||
}
|
||||
this.animateInvalidFields();
|
||||
throw response;
|
||||
|
@ -220,8 +244,8 @@ export default {
|
|||
|
||||
if (response && response.responseText) {
|
||||
const responseText = response.responseText;
|
||||
const start = responseText.indexOf('>') + 1;
|
||||
const end = responseText.indexOf('plugins');
|
||||
const start = responseText.indexOf(">") + 1;
|
||||
const end = responseText.indexOf("plugins");
|
||||
const message = responseText.substring(start, end);
|
||||
this.handleWizardError(message);
|
||||
throw message;
|
||||
|
@ -230,44 +254,44 @@ export default {
|
|||
},
|
||||
|
||||
handleWizardError(message) {
|
||||
this.set('message', {
|
||||
state: 'error',
|
||||
text: message
|
||||
this.set("message", {
|
||||
state: "error",
|
||||
text: message,
|
||||
});
|
||||
Ember.run.later(() => this.set('message', null), 6000);
|
||||
}
|
||||
Ember.run.later(() => this.set("message", null), 6000);
|
||||
},
|
||||
});
|
||||
|
||||
WizardField.reopen({
|
||||
classNameBindings: ['field.id'],
|
||||
classNameBindings: ["field.id"],
|
||||
|
||||
cookedDescription: function() {
|
||||
return cook(this.get('field.description'));
|
||||
}.property('field.description'),
|
||||
cookedDescription: function () {
|
||||
return cook(this.get("field.description"));
|
||||
}.property("field.description"),
|
||||
|
||||
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')
|
||||
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'
|
||||
"text",
|
||||
"number",
|
||||
"textarea",
|
||||
"dropdown",
|
||||
"tag",
|
||||
"image",
|
||||
"user_selector",
|
||||
"text_only",
|
||||
"composer",
|
||||
"category",
|
||||
"group",
|
||||
"date",
|
||||
"time",
|
||||
"date_time",
|
||||
];
|
||||
|
||||
FieldModel.reopen({
|
||||
|
@ -275,7 +299,7 @@ export default {
|
|||
if (this.customCheck) {
|
||||
return this.customCheck();
|
||||
}
|
||||
|
||||
|
||||
let valid = this.valid;
|
||||
|
||||
if (!this.required) {
|
||||
|
@ -283,23 +307,23 @@ export default {
|
|||
return true;
|
||||
}
|
||||
|
||||
const val = this.get('value');
|
||||
const type = this.get('type');
|
||||
|
||||
if (type === 'checkbox') {
|
||||
const val = this.get("value");
|
||||
const type = this.get("type");
|
||||
|
||||
if (type === "checkbox") {
|
||||
valid = val;
|
||||
} else if (type === 'upload') {
|
||||
} 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') {
|
||||
} else if (type === "url") {
|
||||
valid = true;
|
||||
}
|
||||
|
||||
|
||||
this.setValid(valid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -13,4 +13,6 @@
|
|||
showLink=showLink
|
||||
composerEvents=true
|
||||
disabled=disableTextarea
|
||||
outletArgs=(hash composer=composer editorType="composer")}}
|
||||
outletArgs=(hash composer=composer editorType="composer")}}
|
||||
|
||||
{{input class="wizard-composer-upload hidden-upload-field" disabled=uploading type="file" multiple=true }}
|
||||
|
|
|
@ -183,3 +183,7 @@
|
|||
.d-editor-button-bar .btn {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.wizard-composer-upload {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
@import "common/foundation/colors";
|
||||
@import "common/foundation/variables";
|
||||
@import "common/base/code_highlighting";
|
||||
@import "common/base/modal";
|
||||
@import "desktop/modal";
|
||||
@import "custom/base";
|
||||
@import "custom/wizard";
|
||||
@import "custom/step";
|
||||
|
@ -9,5 +12,3 @@
|
|||
@import "custom/composer";
|
||||
@import "custom/events";
|
||||
@import "custom/locations";
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
<%= server_plugin_outlet "custom_wizard" %>
|
||||
|
||||
<%= tag.meta id: 'data-discourse-setup', data: client_side_setup_data %>
|
||||
|
||||
<meta name="discourse_theme_ids" content="<%= theme_ids&.join(",") %>">
|
||||
<meta name="discourse-base-uri" content="<%= Discourse.base_uri %>">
|
||||
|
||||
|
|
Laden …
In neuem Issue referenzieren