IMPROVE: translation feature
Dieser Commit ist enthalten in:
Ursprung
10fb3ee176
Commit
270d3bccf5
32 geänderte Dateien mit 230 neuen und 143 gelöschten Zeilen
|
@ -102,8 +102,12 @@ export default Component.extend({
|
||||||
|
|
||||||
@discourseComputed("isUser", "field", "value")
|
@discourseComputed("isUser", "field", "value")
|
||||||
username(isUser, field, value) {
|
username(isUser, field, value) {
|
||||||
if (isUser) {return value.username;}
|
if (isUser) {
|
||||||
if (field === "username") {return value.value;}
|
return value.username;
|
||||||
|
}
|
||||||
|
if (field === "username") {
|
||||||
|
return value.value;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -111,7 +115,9 @@ export default Component.extend({
|
||||||
|
|
||||||
@discourseComputed("username")
|
@discourseComputed("username")
|
||||||
userProfileUrl(username) {
|
userProfileUrl(username) {
|
||||||
if (username) {return `/u/${username}`;}
|
if (username) {
|
||||||
|
return `/u/${username}`;
|
||||||
|
}
|
||||||
return "/";
|
return "/";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ const step = {
|
||||||
id: null,
|
id: null,
|
||||||
index: null,
|
index: null,
|
||||||
title: null,
|
title: null,
|
||||||
key: null,
|
|
||||||
banner: null,
|
banner: null,
|
||||||
raw_description: null,
|
raw_description: null,
|
||||||
required_data: null,
|
required_data: null,
|
||||||
|
@ -68,7 +67,6 @@ const field = {
|
||||||
description: null,
|
description: null,
|
||||||
property: null,
|
property: null,
|
||||||
required: null,
|
required: null,
|
||||||
key: null,
|
|
||||||
type: null,
|
type: null,
|
||||||
condition: null,
|
condition: null,
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,14 +31,20 @@ CustomWizardLogs.reopenClass({
|
||||||
result.logs = result.logs.map((item) => {
|
result.logs = result.logs.map((item) => {
|
||||||
let map = {};
|
let map = {};
|
||||||
|
|
||||||
if (item.date) {map.date = logItem(item, "date");}
|
if (item.date) {
|
||||||
if (item.action) {map.action = logItem(item, "action");}
|
map.date = logItem(item, "date");
|
||||||
|
}
|
||||||
|
if (item.action) {
|
||||||
|
map.action = logItem(item, "action");
|
||||||
|
}
|
||||||
if (item.user) {
|
if (item.user) {
|
||||||
map.user = item.user;
|
map.user = item.user;
|
||||||
} else {
|
} else {
|
||||||
map.user = logItem(item, "username");
|
map.user = logItem(item, "username");
|
||||||
}
|
}
|
||||||
if (item.message) {map.message = logItem(item, "message");}
|
if (item.message) {
|
||||||
|
map.message = logItem(item, "message");
|
||||||
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
});
|
});
|
||||||
|
|
|
@ -126,25 +126,29 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting">
|
{{#if proSubscribed}}
|
||||||
<div class="setting-label">
|
<div class="setting pro">
|
||||||
<label>{{i18n "admin.wizard.save_submissions"}}</label>
|
<div class="setting-label">
|
||||||
|
<label>{{i18n "admin.wizard.save_submissions"}}</label>
|
||||||
|
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="setting-value">
|
||||||
|
{{input type="checkbox" checked=wizard.save_submissions}}
|
||||||
|
<span>{{i18n "admin.wizard.save_submissions_label"}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-value">
|
|
||||||
{{input type="checkbox" checked=wizard.save_submissions}}
|
|
||||||
<span>{{i18n "admin.wizard.save_submissions_label"}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting">
|
<div class="setting pro">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n "admin.wizard.restart_on_revisit"}}</label>
|
<label>{{i18n "admin.wizard.restart_on_revisit"}}</label>
|
||||||
|
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="setting-value">
|
||||||
|
{{input type="checkbox" checked=wizard.restart_on_revisit}}
|
||||||
|
<span>{{i18n "admin.wizard.restart_on_revisit_label"}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-value">
|
{{/if}}
|
||||||
{{input type="checkbox" checked=wizard.restart_on_revisit}}
|
|
||||||
<span>{{i18n "admin.wizard.restart_on_revisit_label"}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{wizard-links
|
{{wizard-links
|
||||||
|
|
|
@ -253,19 +253,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<div class="setting pro">
|
|
||||||
<div class="setting-label">
|
|
||||||
<label>{{i18n "admin.wizard.translation"}}</label>
|
|
||||||
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="setting-value">
|
|
||||||
{{input
|
|
||||||
name="key"
|
|
||||||
value=field.key
|
|
||||||
placeholderKey="admin.wizard.translation_placeholder"}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if validations}}
|
{{#if validations}}
|
||||||
{{wizard-realtime-validations field=field validations=validations}}
|
{{wizard-realtime-validations field=field validations=validations}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -100,19 +100,6 @@
|
||||||
)}}
|
)}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="setting pro">
|
|
||||||
<div class="setting-label">
|
|
||||||
<label>{{i18n "admin.wizard.translation"}}</label>
|
|
||||||
<span class="pro-label">{{i18n "admin.wizard.pro.label"}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="setting-value">
|
|
||||||
{{input
|
|
||||||
name="key"
|
|
||||||
value=step.key
|
|
||||||
placeholderKey="admin.wizard.translation_placeholder"}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{wizard-links
|
{{wizard-links
|
||||||
|
|
|
@ -33,7 +33,7 @@ export default ComposerEditor.extend({
|
||||||
lastValidatedAt: "lastValidatedAt",
|
lastValidatedAt: "lastValidatedAt",
|
||||||
popupMenuOptions: [],
|
popupMenuOptions: [],
|
||||||
draftStatus: "null",
|
draftStatus: "null",
|
||||||
replyPlaceholder: alias("field.placeholder"),
|
replyPlaceholder: alias("field.translatedPlaceholder"),
|
||||||
|
|
||||||
@on("didInsertElement")
|
@on("didInsertElement")
|
||||||
_composerEditorInit() {
|
_composerEditorInit() {
|
||||||
|
|
|
@ -16,19 +16,23 @@ export default {
|
||||||
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({
|
FieldComponent.reopen({
|
||||||
classNameBindings: ["field.id"],
|
classNameBindings: ["field.id"],
|
||||||
|
|
||||||
|
@discourseComputed("field.translatedDescription")
|
||||||
|
cookedDescription(description) {
|
||||||
|
return cook(description);
|
||||||
|
},
|
||||||
|
|
||||||
@discourseComputed("field.type")
|
@discourseComputed("field.type")
|
||||||
textType(fieldType) {
|
textType(fieldType) {
|
||||||
return ["text", "textarea"].includes(fieldType);
|
return ["text", "textarea"].includes(fieldType);
|
||||||
},
|
},
|
||||||
|
|
||||||
cookedDescription: function () {
|
|
||||||
return cook(this.get("field.description"));
|
|
||||||
}.property("field.description"),
|
|
||||||
|
|
||||||
inputComponentName: function () {
|
inputComponentName: function () {
|
||||||
const type = this.get("field.type");
|
const type = this.get("field.type");
|
||||||
const id = this.get("field.id");
|
const id = this.get("field.id");
|
||||||
|
@ -57,6 +61,26 @@ export default {
|
||||||
];
|
];
|
||||||
|
|
||||||
FieldModel.reopen({
|
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() {
|
check() {
|
||||||
if (this.customCheck) {
|
if (this.customCheck) {
|
||||||
return this.customCheck();
|
return this.customCheck();
|
||||||
|
|
|
@ -22,8 +22,26 @@ export default {
|
||||||
).cook;
|
).cook;
|
||||||
const { schedule } = requirejs("@ember/runloop");
|
const { schedule } = requirejs("@ember/runloop");
|
||||||
const { alias, not } = requirejs("@ember/object/computed");
|
const { alias, not } = requirejs("@ember/object/computed");
|
||||||
|
const { translatedText } = requirejs(
|
||||||
|
"discourse/plugins/discourse-custom-wizard/wizard/lib/wizard-i18n"
|
||||||
|
);
|
||||||
|
|
||||||
StepModel.reopen({
|
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() {
|
save() {
|
||||||
const wizardId = this.get("wizardId");
|
const wizardId = this.get("wizardId");
|
||||||
const fields = {};
|
const fields = {};
|
||||||
|
@ -128,13 +146,15 @@ export default {
|
||||||
return index === 0 && !required;
|
return index === 0 && !required;
|
||||||
}.property("step.index", "wizard.required"),
|
}.property("step.index", "wizard.required"),
|
||||||
|
|
||||||
cookedTitle: function () {
|
@discourseComputed("step.translatedTitle")
|
||||||
return cook(this.get("step.title"));
|
cookedTitle(title) {
|
||||||
}.property("step.title"),
|
return cook(title);
|
||||||
|
},
|
||||||
|
|
||||||
cookedDescription: function () {
|
@discourseComputed("step.translatedDescription")
|
||||||
return cook(this.get("step.description"));
|
cookedDescription(description) {
|
||||||
}.property("step.description"),
|
return cook(description);
|
||||||
|
},
|
||||||
|
|
||||||
bannerImage: function () {
|
bannerImage: function () {
|
||||||
const src = this.get("step.banner");
|
const src = this.get("step.banner");
|
||||||
|
|
|
@ -20,13 +20,25 @@ const translationExists = (key) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getThemeKey = (key) => {
|
||||||
|
const themeId = getThemeId();
|
||||||
|
return `theme_translations.${themeId}.${key}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const translatedText = (key, value) => {
|
||||||
|
const themeKey = getThemeKey(key);
|
||||||
|
return translationExists(themeKey) ? I18n.t(themeKey) : value;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { translatedText };
|
||||||
|
|
||||||
const WizardI18n = (key, params = {}) => {
|
const WizardI18n = (key, params = {}) => {
|
||||||
const themeId = getThemeId();
|
const themeId = getThemeId();
|
||||||
if (!themeId) {
|
if (!themeId) {
|
||||||
return I18n.t(key, params);
|
return I18n.t(key, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeKey = `theme_translations.${themeId}.${key}`;
|
let themeKey = getThemeKey(key);
|
||||||
|
|
||||||
if (translationExists(themeKey)) {
|
if (translationExists(themeKey)) {
|
||||||
return I18n.t(themeKey, params);
|
return I18n.t(themeKey, params);
|
||||||
|
|
|
@ -41,6 +41,7 @@ CustomWizard.reopenClass({
|
||||||
wizardJson.steps = wizardJson.steps
|
wizardJson.steps = wizardJson.steps
|
||||||
.map((step) => {
|
.map((step) => {
|
||||||
const stepObj = Step.create(step);
|
const stepObj = Step.create(step);
|
||||||
|
stepObj.wizardId = wizardJson.id;
|
||||||
|
|
||||||
stepObj.fields.sort((a, b) => {
|
stepObj.fields.sort((a, b) => {
|
||||||
return parseFloat(a.number) - parseFloat(b.number);
|
return parseFloat(a.number) - parseFloat(b.number);
|
||||||
|
@ -57,7 +58,11 @@ CustomWizard.reopenClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stepObj.fields = stepObj.fields.map((f) => WizardField.create(f));
|
stepObj.fields = stepObj.fields.map((f) => {
|
||||||
|
f.wizardId = wizardJson.id;
|
||||||
|
f.stepId = stepObj.id;
|
||||||
|
return WizardField.create(f);
|
||||||
|
});
|
||||||
|
|
||||||
return stepObj;
|
return stepObj;
|
||||||
})
|
})
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{input id=field.id value=field.value class=fieldClass placeholder=field.placeholder tabindex=field.tabindex autocomplete=autocomplete}}
|
{{input id=field.id value=field.value class=fieldClass placeholder=field.translatedPlaceholder tabindex=field.tabindex autocomplete=autocomplete}}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{textarea id=field.id value=field.value class=fieldClass placeholder=field.placeholder tabindex=field.tabindex}}
|
{{textarea id=field.id value=field.value class=fieldClass placeholder=field.translatedPlaceholder tabindex=field.tabindex}}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<label for={{field.id}} class="field-label">
|
<label for={{field.id}} class="field-label">
|
||||||
{{html-safe field.label}}
|
{{html-safe field.translatedLabel}}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
{{#if field.image}}
|
{{#if field.image}}
|
||||||
|
|
|
@ -44,8 +44,6 @@ en:
|
||||||
key: "Key"
|
key: "Key"
|
||||||
value: "Value"
|
value: "Value"
|
||||||
profile: "profile"
|
profile: "profile"
|
||||||
translation: "Translation"
|
|
||||||
translation_placeholder: "key"
|
|
||||||
type: "Type"
|
type: "Type"
|
||||||
none: "Make a selection"
|
none: "Make a selection"
|
||||||
submission_key: 'submission key'
|
submission_key: 'submission key'
|
||||||
|
@ -174,10 +172,10 @@ en:
|
||||||
banner: "Banner"
|
banner: "Banner"
|
||||||
description: "Description"
|
description: "Description"
|
||||||
required_data:
|
required_data:
|
||||||
label: "Required"
|
label: "Required Data"
|
||||||
not_permitted_message: "Message shown when required data not present"
|
not_permitted_message: "Message shown when required data not present"
|
||||||
permitted_params:
|
permitted_params:
|
||||||
label: "Params"
|
label: "Permitted Params"
|
||||||
force_final:
|
force_final:
|
||||||
label: "Conditional Final Step"
|
label: "Conditional Final Step"
|
||||||
description: "Display this step as the final step if conditions on later steps have not passed when the user reaches this step."
|
description: "Display this step as the final step if conditions on later steps have not passed when the user reaches this step."
|
||||||
|
|
|
@ -11,7 +11,6 @@ class CustomWizard::Field
|
||||||
:label,
|
:label,
|
||||||
:description,
|
:description,
|
||||||
:image,
|
:image,
|
||||||
:key,
|
|
||||||
:validations,
|
:validations,
|
||||||
:min_length,
|
:min_length,
|
||||||
:max_length,
|
:max_length,
|
||||||
|
@ -36,7 +35,6 @@ class CustomWizard::Field
|
||||||
@value = attrs[:value] || default_value
|
@value = attrs[:value] || default_value
|
||||||
@description = attrs[:description]
|
@description = attrs[:description]
|
||||||
@image = attrs[:image]
|
@image = attrs[:image]
|
||||||
@key = attrs[:key]
|
|
||||||
@validations = attrs[:validations]
|
@validations = attrs[:validations]
|
||||||
@min_length = attrs[:min_length]
|
@min_length = attrs[:min_length]
|
||||||
@max_length = attrs[:max_length]
|
@max_length = attrs[:max_length]
|
||||||
|
|
|
@ -9,7 +9,6 @@ class CustomWizard::Step
|
||||||
attr_accessor :index,
|
attr_accessor :index,
|
||||||
:title,
|
:title,
|
||||||
:description,
|
:description,
|
||||||
:key,
|
|
||||||
:permitted,
|
:permitted,
|
||||||
:permitted_message,
|
:permitted_message,
|
||||||
:fields,
|
:fields,
|
||||||
|
|
|
@ -54,10 +54,15 @@ class CustomWizard::TemplateValidator
|
||||||
|
|
||||||
def self.pro
|
def self.pro
|
||||||
{
|
{
|
||||||
wizard: {},
|
wizard: {
|
||||||
|
save_submissions: 'false',
|
||||||
|
restart_on_revisit: 'true',
|
||||||
|
},
|
||||||
step: {
|
step: {
|
||||||
condition: 'present',
|
condition: 'present',
|
||||||
index: 'conditional'
|
index: 'conditional',
|
||||||
|
required_data: 'present',
|
||||||
|
permitted_params: 'present'
|
||||||
},
|
},
|
||||||
field: {
|
field: {
|
||||||
condition: 'present',
|
condition: 'present',
|
||||||
|
@ -87,10 +92,12 @@ class CustomWizard::TemplateValidator
|
||||||
|
|
||||||
def validate_pro(object, type)
|
def validate_pro(object, type)
|
||||||
self.class.pro[type].each do |property, pro_type|
|
self.class.pro[type].each do |property, pro_type|
|
||||||
is_pro = object[property.to_s].present? && (
|
val = object[property.to_s]
|
||||||
pro_type === 'present' ||
|
is_pro = (val != nil) && (
|
||||||
(pro_type === 'conditional' && object[property.to_s].is_a?(Hash)) ||
|
pro_type === 'present' && val.present? ||
|
||||||
(pro_type.is_a?(Array) && pro_type.include?(object[property.to_s]))
|
(['true', 'false'].include?(pro_type) && cast_bool(val) == cast_bool(pro_type)) ||
|
||||||
|
(pro_type === 'conditional' && val.is_a?(Hash)) ||
|
||||||
|
(pro_type.is_a?(Array) && pro_type.include?(val))
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_pro && !@pro.subscribed?
|
if is_pro && !@pro.subscribed?
|
||||||
|
@ -122,4 +129,8 @@ class CustomWizard::TemplateValidator
|
||||||
errors.add :base, I18n.t("wizard.validation.after_time")
|
errors.add :base, I18n.t("wizard.validation.after_time")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cast_bool(val)
|
||||||
|
ActiveRecord::Type::Boolean.new.cast(val)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -41,13 +41,8 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
object.value
|
object.value
|
||||||
end
|
end
|
||||||
|
|
||||||
def i18n_key
|
|
||||||
@i18n_key ||= "wizard.step.#{object.step.id}.fields.#{object.id}".underscore
|
|
||||||
end
|
|
||||||
|
|
||||||
def label
|
def label
|
||||||
return object.label if object.label.present?
|
I18n.t("#{i18n_key}.label", default: object.label, base_url: Discourse.base_url)
|
||||||
I18n.t("#{object.key || i18n_key}.label", default: '')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_label?
|
def include_label?
|
||||||
|
@ -55,14 +50,21 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def description
|
def description
|
||||||
return object.description if object.description.present?
|
I18n.t("#{i18n_key}.description", default: object.description, base_url: Discourse.base_url)
|
||||||
I18n.t("#{object.key || i18n_key}.description", default: '', base_url: Discourse.base_url)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_description?
|
def include_description?
|
||||||
description.present?
|
description.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def placeholder
|
||||||
|
I18n.t("#{i18n_key}.placeholder", default: object.placeholder)
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_placeholder?
|
||||||
|
placeholder.present?
|
||||||
|
end
|
||||||
|
|
||||||
def image
|
def image
|
||||||
object.image
|
object.image
|
||||||
end
|
end
|
||||||
|
@ -71,15 +73,6 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
object.image.present?
|
object.image.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def placeholder
|
|
||||||
return object.placeholder if object.placeholder.present?
|
|
||||||
I18n.t("#{object.key || i18n_key}.placeholder", default: '')
|
|
||||||
end
|
|
||||||
|
|
||||||
def include_placeholder?
|
|
||||||
placeholder.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def file_types
|
def file_types
|
||||||
object.file_types
|
object.file_types
|
||||||
end
|
end
|
||||||
|
@ -122,4 +115,14 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
def preview_template
|
def preview_template
|
||||||
object.preview_template
|
object.preview_template
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def i18n_key
|
||||||
|
@i18n_key ||= "#{object.step.wizard.id}.#{object.step.id}.#{object.id}".underscore
|
||||||
|
end
|
||||||
|
|
||||||
|
def subscribed?
|
||||||
|
@subscribed ||= CustomWizard::Pro.subscribed?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,8 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
|
||||||
:required,
|
:required,
|
||||||
:permitted,
|
:permitted,
|
||||||
:uncategorized_category_id,
|
:uncategorized_category_id,
|
||||||
:categories
|
:categories,
|
||||||
|
:pro_subscribed
|
||||||
|
|
||||||
has_many :steps, serializer: ::CustomWizard::StepSerializer, embed: :objects
|
has_many :steps, serializer: ::CustomWizard::StepSerializer, embed: :objects
|
||||||
has_one :user, serializer: ::BasicUserSerializer, embed: :objects
|
has_one :user, serializer: ::BasicUserSerializer, embed: :objects
|
||||||
|
@ -60,4 +61,8 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
|
||||||
def categories
|
def categories
|
||||||
object.categories.map { |c| c.to_h }
|
object.categories.map { |c| c.to_h }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def pro_subscribed
|
||||||
|
CustomWizard::Pro.subscribed?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,13 +39,8 @@ class CustomWizard::StepSerializer < ::ApplicationSerializer
|
||||||
object.previous.present?
|
object.previous.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def i18n_key
|
|
||||||
@i18n_key ||= "wizard.step.#{object.id}".underscore
|
|
||||||
end
|
|
||||||
|
|
||||||
def title
|
def title
|
||||||
return PrettyText.cook(object.title) if object.title
|
I18n.t("#{i18n_key}.title", default: object.title, base_url: Discourse.base_url)
|
||||||
PrettyText.cook(I18n.t("#{object.key || i18n_key}.title", default: ''))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_title?
|
def include_title?
|
||||||
|
@ -53,8 +48,7 @@ class CustomWizard::StepSerializer < ::ApplicationSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def description
|
def description
|
||||||
return object.description if object.description
|
I18n.t("#{i18n_key}.description", default: object.description, base_url: Discourse.base_url)
|
||||||
PrettyText.cook(I18n.t("#{object.key || i18n_key}.description", default: '', base_url: Discourse.base_url))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_description?
|
def include_description?
|
||||||
|
@ -80,4 +74,14 @@ class CustomWizard::StepSerializer < ::ApplicationSerializer
|
||||||
def final
|
def final
|
||||||
object.final?
|
object.final?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def i18n_key
|
||||||
|
@i18n_key ||= "#{object.wizard.id}.#{object.id}".underscore
|
||||||
|
end
|
||||||
|
|
||||||
|
def subscribed?
|
||||||
|
@subscribed ||= CustomWizard::Pro.subscribed?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -176,7 +176,7 @@ describe CustomWizard::Action do
|
||||||
|
|
||||||
context "pro actions" do
|
context "pro actions" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
end
|
end
|
||||||
|
|
||||||
it '#send_message' do
|
it '#send_message' do
|
||||||
|
|
|
@ -176,6 +176,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context "restart is enabled" do
|
context "restart is enabled" do
|
||||||
before do
|
before do
|
||||||
|
enable_subscription
|
||||||
@template[:restart_on_revisit] = true
|
@template[:restart_on_revisit] = true
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
end
|
end
|
||||||
|
@ -204,6 +205,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context 'with required data' do
|
context 'with required data' do
|
||||||
before do
|
before do
|
||||||
|
enable_subscription
|
||||||
@template[:steps][0][:required_data] = required_data_json['required_data']
|
@template[:steps][0][:required_data] = required_data_json['required_data']
|
||||||
@template[:steps][0][:required_data_message] = required_data_json['required_data_message']
|
@template[:steps][0][:required_data_message] = required_data_json['required_data_message']
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
|
@ -239,6 +241,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context "with permitted params" do
|
context "with permitted params" do
|
||||||
before do
|
before do
|
||||||
|
enable_subscription
|
||||||
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params']
|
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params']
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
end
|
end
|
||||||
|
@ -253,7 +256,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context "with condition" do
|
context "with condition" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
@template[:steps][0][:condition] = user_condition_json['condition']
|
@template[:steps][0][:condition] = user_condition_json['condition']
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
end
|
end
|
||||||
|
@ -292,7 +295,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context "with condition" do
|
context "with condition" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition']
|
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition']
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
end
|
end
|
||||||
|
@ -324,6 +327,7 @@ describe CustomWizard::Builder do
|
||||||
|
|
||||||
context 'save submissions disabled' do
|
context 'save submissions disabled' do
|
||||||
before do
|
before do
|
||||||
|
enable_subscription
|
||||||
@template[:save_submissions] = false
|
@template[:save_submissions] = false
|
||||||
CustomWizard::Template.save(@template.as_json)
|
CustomWizard::Template.save(@template.as_json)
|
||||||
@wizard = CustomWizard::Builder.new(@template[:id], user).build
|
@wizard = CustomWizard::Builder.new(@template[:id], user).build
|
||||||
|
|
|
@ -217,7 +217,7 @@ describe CustomWizard::CustomField do
|
||||||
|
|
||||||
context "with a pro subscription" do
|
context "with a pro subscription" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
end
|
end
|
||||||
|
|
||||||
it "saves pro field types" do
|
it "saves pro field types" do
|
||||||
|
|
|
@ -23,7 +23,6 @@ describe CustomWizard::Field do
|
||||||
expect(field.image).to eq("field_image_url.png")
|
expect(field.image).to eq("field_image_url.png")
|
||||||
expect(field.description).to eq("Field description")
|
expect(field.description).to eq("Field description")
|
||||||
expect(field.required).to eq(true)
|
expect(field.required).to eq(true)
|
||||||
expect(field.key).to eq("field.locale.key")
|
|
||||||
expect(field.type).to eq("field_type")
|
expect(field.type).to eq("field_type")
|
||||||
expect(field.content).to eq([])
|
expect(field.content).to eq([])
|
||||||
end
|
end
|
||||||
|
|
|
@ -359,7 +359,7 @@ describe CustomWizard::Mapper do
|
||||||
|
|
||||||
context "with a pro subscription" do
|
context "with a pro subscription" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
end
|
end
|
||||||
|
|
||||||
it "treats replaced values as string literals" do
|
it "treats replaced values as string literals" do
|
||||||
|
|
|
@ -43,47 +43,63 @@ describe CustomWizard::TemplateValidator do
|
||||||
).to eq(false)
|
).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "invalidates pro step attributes without a pro subscription" do
|
context "without subscription" do
|
||||||
template[:steps][0][:condition] = user_condition['condition']
|
it "invalidates subscription wizard attributes" do
|
||||||
expect(
|
template[:save_submissions] = false
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
expect(
|
||||||
).to eq(false)
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
end
|
).to eq(false)
|
||||||
|
|
||||||
it "invalidates pro field attributes without a pro subscription" do
|
|
||||||
template[:steps][0][:fields][0][:condition] = user_condition['condition']
|
|
||||||
expect(
|
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
|
||||||
).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "invalidates pro actions without a pro subscription" do
|
|
||||||
template[:actions] << create_category
|
|
||||||
expect(
|
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
|
||||||
).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with pro subscription" do
|
|
||||||
before do
|
|
||||||
enable_pro
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "validates pro step attributes" do
|
it "invalidates subscription step attributes" do
|
||||||
|
template[:steps][0][:condition] = user_condition['condition']
|
||||||
|
expect(
|
||||||
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
|
).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "invalidates subscription field attributes" do
|
||||||
|
template[:steps][0][:fields][0][:condition] = user_condition['condition']
|
||||||
|
expect(
|
||||||
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
|
).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "invalidates subscription actions" do
|
||||||
|
template[:actions] << create_category
|
||||||
|
expect(
|
||||||
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
|
).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with subscription" do
|
||||||
|
before do
|
||||||
|
enable_subscription
|
||||||
|
end
|
||||||
|
|
||||||
|
it "validates wizard attributes" do
|
||||||
|
template[:save_submissions] = false
|
||||||
|
expect(
|
||||||
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
|
).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "validates step attributes" do
|
||||||
template[:steps][0][:condition] = user_condition['condition']
|
template[:steps][0][:condition] = user_condition['condition']
|
||||||
expect(
|
expect(
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
).to eq(true)
|
).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "validates pro field attributes" do
|
it "validates field attributes" do
|
||||||
template[:steps][0][:fields][0][:condition] = user_condition['condition']
|
template[:steps][0][:fields][0][:condition] = user_condition['condition']
|
||||||
expect(
|
expect(
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
).to eq(true)
|
).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "validates pro actions" do
|
it "validates actions" do
|
||||||
template[:actions] << create_category
|
template[:actions] << create_category
|
||||||
expect(
|
expect(
|
||||||
CustomWizard::TemplateValidator.new(template).perform
|
CustomWizard::TemplateValidator.new(template).perform
|
||||||
|
|
|
@ -74,7 +74,7 @@ describe "custom field extensions" do
|
||||||
|
|
||||||
context "pro custom fields" do
|
context "pro custom fields" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
|
|
||||||
pro_custom_field_json['custom_fields'].each do |field_json|
|
pro_custom_field_json['custom_fields'].each do |field_json|
|
||||||
custom_field = CustomWizard::CustomField.new(nil, field_json)
|
custom_field = CustomWizard::CustomField.new(nil, field_json)
|
||||||
|
|
|
@ -28,7 +28,7 @@ def authenticate_pro
|
||||||
CustomWizard::ProAuthentication.any_instance.stubs(:active?).returns(true)
|
CustomWizard::ProAuthentication.any_instance.stubs(:active?).returns(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def enable_pro
|
def enable_subscription
|
||||||
CustomWizard::Pro.any_instance.stubs(:subscribed?).returns(true)
|
CustomWizard::Pro.any_instance.stubs(:subscribed?).returns(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ describe "custom field extensions" do
|
||||||
|
|
||||||
context "with a pro subscription" do
|
context "with a pro subscription" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
|
|
||||||
pro_custom_field_json['custom_fields'].each do |field_json|
|
pro_custom_field_json['custom_fields'].each do |field_json|
|
||||||
custom_field = CustomWizard::CustomField.new(nil, field_json)
|
custom_field = CustomWizard::CustomField.new(nil, field_json)
|
||||||
|
|
|
@ -121,7 +121,7 @@ describe CustomWizard::StepsController do
|
||||||
|
|
||||||
context "pro" do
|
context "pro" do
|
||||||
before do
|
before do
|
||||||
enable_pro
|
enable_subscription
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when user cant see the step due to conditions" do
|
it "raises an error when user cant see the step due to conditions" do
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe CustomWizard::StepSerializer do
|
||||||
each_serializer: described_class,
|
each_serializer: described_class,
|
||||||
scope: Guardian.new(user)
|
scope: Guardian.new(user)
|
||||||
).as_json
|
).as_json
|
||||||
expect(json_array[0][:title]).to eq("<p>Text</p>")
|
expect(json_array[0][:title]).to eq("Text")
|
||||||
expect(json_array[0][:description]).to eq("<p>Text inputs!</p>")
|
expect(json_array[0][:description]).to eq("<p>Text inputs!</p>")
|
||||||
expect(json_array[1][:index]).to eq(1)
|
expect(json_array[1][:index]).to eq(1)
|
||||||
end
|
end
|
||||||
|
@ -34,6 +34,7 @@ describe CustomWizard::StepSerializer do
|
||||||
|
|
||||||
context 'with required data' do
|
context 'with required data' do
|
||||||
before do
|
before do
|
||||||
|
enable_subscription
|
||||||
wizard_template['steps'][0]['required_data'] = required_data_json['required_data']
|
wizard_template['steps'][0]['required_data'] = required_data_json['required_data']
|
||||||
wizard_template['steps'][0]['required_data_message'] = required_data_json['required_data_message']
|
wizard_template['steps'][0]['required_data_message'] = required_data_json['required_data_message']
|
||||||
CustomWizard::Template.save(wizard_template)
|
CustomWizard::Template.save(wizard_template)
|
||||||
|
|
Laden …
In neuem Issue referenzieren