0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-14 05:52:52 +01:00
discourse-custom-wizard/assets/javascripts/wizard/initializers/custom.js.es6

274 Zeilen
8,2 KiB
Text

import { default as computed } from 'ember-addons/ember-computed-decorators';
2017-09-25 16:47:40 +02:00
export default {
name: 'custom-routes',
initialize(app) {
2017-11-02 02:41:26 +01:00
if (window.location.pathname.indexOf('/w/') < 0) return;
const Router = requirejs('wizard/router').default;
2017-10-13 15:02:34 +02:00
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;
2017-10-05 02:36:46 +02:00
const WizardStep = requirejs('wizard/components/wizard-step').default;
const WizardField = requirejs('wizard/components/wizard-field').default;
2017-10-05 02:36:46 +02:00
const getUrl = requirejs('discourse-common/lib/get-url').default;
2017-10-09 07:52:09 +02:00
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 WizardFieldDropdown = requirejs('wizard/components/wizard-field-dropdown').default;
WizardFieldDropdown.reopen({
tagName: 'span',
classNames: ['wizard-select-value'],
@computed
isFlagSelector() {
const field = this.get('field');
//TODO improve the way this detects a flag dropdown (currently it relies on the string 'Nation', e.g. 'Nationality' or 'National Flag' appearing in label)
return (field.label.includes('Nation')) ? true : false;
}
});
// 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]]];
return resArray;
};
$.fn.autocomplete = autocomplete;
const targets = ["controller", "component", "route", "model", "adapter"];
const siteSettings = Wizard.SiteSettings;
app.register("site-settings:main", siteSettings, { instantiate: false });
targets.forEach(t => app.inject(t, "siteSettings", "site-settings:main"));
const site = Discourse.Site;
app.register("site:main", site);
targets.forEach(t => app.inject(t, "site", "site:main"));
site.reopenClass(Singleton);
site.currentProp('can_create_tag', false);
// this is for discourse/lib/utilities.avatarImg;
Discourse.__container__ = app.__container__;
Discourse.getURLWithCDN = getUrl;
Discourse.getURL = getUrl;
2017-10-13 15:02:34 +02:00
Router.reopen({
rootURL: getUrl('/w/')
});
2017-09-25 16:47:40 +02:00
Router.map(function() {
2017-10-13 15:02:34 +02:00
this.route('custom', { path: '/:wizard_id' }, function() {
2017-10-22 05:37:58 +02:00
this.route('steps');
2017-09-25 16:47:40 +02:00
this.route('step', { path: '/steps/:step_id' });
});
});
2017-10-13 15:02:34 +02:00
ApplicationRoute.reopen({
redirect() {
this.transitionTo('custom');
2017-10-15 05:58:22 +02:00
},
model() {}
});
2017-10-05 02:36:46 +02:00
WizardStep.reopen({
classNameBindings: ['step.id'],
2018-02-04 10:23:28 +01:00
animateInvalidFields() {
Ember.run.scheduleOnce('afterRender', () => {
2019-07-31 09:42:50 +02:00
$('.invalid input[type=text], .invalid textarea, .invalid input[type=checkbox], .invalid .select-kit').wiggle(2, 100);
2018-02-04 10:23:28 +01:00
});
},
2018-02-01 06:11:23 +01:00
ensureStartsAtTop: function() {
window.scrollTo(0,0);
}.observes('step.id'),
2017-11-01 05:21:14 +01:00
showQuitButton: function() {
const index = this.get('step.index');
const required = this.get('wizard.required');
return index === 0 && !required;
}.property('step.index', 'wizard.required'),
2019-06-19 06:32:03 +02:00
cookedTitle: function() {
return cook(this.get('step.title'));
}.property('step.title'),
cookedDescription: function() {
return cook(this.get('step.description'));
}.property('step.description'),
2017-10-06 04:59:02 +02:00
bannerImage: function() {
const src = this.get('step.banner');
if (!src) return;
2018-05-24 07:34:58 +02:00
return getUrl(src);
2017-10-06 04:59:02 +02:00
}.property('step.banner'),
2017-10-13 15:02:34 +02:00
handleMessage: function() {
const message = this.get('step.message');
this.sendAction('showMessage', message);
}.observes('step.message'),
2017-10-05 02:36:46 +02:00
advance() {
this.set('saving', true);
this.get('step').save()
.then(response => {
if (this.get('finalStep')) {
CustomWizard.finished(response);
2017-10-05 02:36:46 +02:00
} else {
this.sendAction('goNext', response);
}
})
.catch(() => this.animateInvalidFields())
.finally(() => this.set('saving', false));
},
actions: {
quit() {
this.get('wizard').skip();
},
done() {
this.set('finalStep', true);
this.send('nextStep');
2017-10-13 15:02:34 +02:00
},
showMessage(message) {
this.sendAction('showMessage', message);
2017-10-05 02:36:46 +02:00
}
}
});
2017-10-09 07:52:09 +02:00
2017-10-13 15:02:34 +02:00
StepModel.reopen({
save() {
const wizardId = this.get('wizardId');
const fields = {};
2018-05-24 07:34:58 +02:00
this.get('fields').forEach(f => {
if (f.type !== 'text-only') {
fields[f.id] = f.value;
}
});
2017-10-13 15:02:34 +02:00
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'));
}
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);
}
});
WizardField.reopen({
classNameBindings: ['field.id'],
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 (type === 'text-only') return false;
return (type === 'component') ? Ember.String.dasherize(id) : `wizard-field-${type}`;
}.property('field.type', 'field.id')
});
2019-07-31 08:57:25 +02:00
const StandardFieldValidation = [
'text',
'textarea',
'dropdown',
'tag',
'image',
'user-selector',
'text-only',
'composer'
];
2017-10-09 07:52:09 +02:00
FieldModel.reopen({
hasCustomCheck: false,
customCheck() {
return true;
},
2017-10-09 07:52:09 +02:00
check() {
let valid = this.get('valid');
if (!this.get('required')) {
this.setValid(true);
return true;
}
const hasCustomCheck = this.get('hasCustomCheck');
if (hasCustomCheck) {
valid = this.customCheck();
} else {
2017-10-09 07:52:09 +02:00
const val = this.get('value');
const type = this.get('type');
if (type === 'checkbox') {
valid = val;
2019-07-31 09:42:50 +02:00
} else if (type === 'category') {
valid = val && val.toString().length > 0;
} else if (type === 'upload') {
valid = val && val.id > 0;
2018-05-16 09:19:03 +02:00
} else if (StandardFieldValidation.indexOf(type) > -1) {
2019-07-31 09:42:50 +02:00
valid = val && val.length > 0;
}
2017-10-09 07:52:09 +02:00
}
2019-07-31 09:42:50 +02:00
this.setValid(valid);
2017-10-09 07:52:09 +02:00
return valid;
}
});
2017-09-25 16:47:40 +02:00
}
};