0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-22 09:20:29 +01:00

Merge branch 'main' into admin-acceptance-tests

Dieser Commit ist enthalten in:
jumagura 2023-03-30 21:22:44 -04:00
Commit 0f59c9092f
27 geänderte Dateien mit 176 neuen und 64 gelöschten Zeilen

Datei anzeigen

@ -3,6 +3,7 @@ import discourseComputed from "discourse-common/utils/decorators";
export default DateInput.extend({
useNativePicker: false,
classNameBindings: ["fieldClass"],
@discourseComputed()
placeholder() {

Datei anzeigen

@ -2,6 +2,8 @@ import DateTimeInput from "discourse/components/date-time-input";
import discourseComputed from "discourse-common/utils/decorators";
export default DateTimeInput.extend({
classNameBindings: ["fieldClass"],
@discourseComputed("timeFirst", "tabindex")
timeTabindex(timeFirst, tabindex) {
return timeFirst ? tabindex : tabindex + 1;

Datei anzeigen

@ -2,6 +2,8 @@ import Component from "@ember/component";
import { observes } from "discourse-common/utils/decorators";
export default Component.extend({
classNameBindings: ["fieldClass"],
@observes("time")
setValue() {
this.set("field.value", this.time.format(this.field.format));

Datei anzeigen

@ -4,7 +4,7 @@ import { computed } from "@ember/object";
export default Component.extend(UppyUploadMixin, {
classNames: ["wizard-field-upload"],
classNameBindings: ["isImage"],
classNameBindings: ["isImage", "fieldClass"],
uploading: false,
type: computed(function () {
return `wizard_${this.field.id}`;

Datei anzeigen

@ -1,3 +1,5 @@
import Component from "@ember/component";
export default Component.extend({});
export default Component.extend({
classNameBindings: ["fieldClass"],
});

Datei anzeigen

@ -9,6 +9,7 @@ import CustomWizard, {
updateCachedWizard,
} from "discourse/plugins/discourse-custom-wizard/discourse/models/custom-wizard";
import { alias, not } from "@ember/object/computed";
import discourseLater from "discourse-common/lib/later";
const alreadyWarned = {};
@ -110,29 +111,22 @@ export default Component.extend({
},
autoFocus() {
schedule("afterRender", () => {
const $invalid = $(
".wizard-field.invalid:nth-of-type(1) .wizard-focusable"
);
if ($invalid.length) {
return $invalid.focus();
}
$(".wizard-focusable:first").focus();
discourseLater(() => {
schedule("afterRender", () => {
if ($(".invalid .wizard-focusable").length) {
this.animateInvalidFields();
}
});
});
},
animateInvalidFields() {
schedule("afterRender", () => {
let $element = $(
".invalid input[type=text],.invalid textarea,.invalid input[type=checkbox],.invalid .select-kit"
);
if ($element.length) {
let $invalid = $(".invalid .wizard-focusable");
if ($invalid.length) {
$([document.documentElement, document.body]).animate(
{
scrollTop: $element.offset().top - 200,
scrollTop: $invalid.offset().top - 200,
},
400
);

Datei anzeigen

@ -1,22 +0,0 @@
import { registerUnbound } from "discourse-common/lib/helpers";
import I18n from "I18n";
import Handlebars from "handlebars";
export default registerUnbound("char-counter", function (body, maxLength) {
let bodyLength = body ? body.length : 0;
let finalString;
if (maxLength) {
let isOverMax = bodyLength > maxLength ? "true" : "false";
finalString = `<div class="body-length" data-length=${bodyLength} data-over-max=${isOverMax}>${bodyLength} / ${I18n.t(
"wizard.x_characters",
{ count: parseInt(maxLength, 10) }
)}</div>`;
} else {
finalString = `<div class="body-length">${I18n.t("wizard.x_characters", {
count: parseInt(bodyLength, 10),
})}</div>`;
}
return new Handlebars.SafeString(finalString);
});

Datei anzeigen

@ -0,0 +1,25 @@
import { registerUnbound } from "discourse-common/lib/helpers";
import I18n from "I18n";
import Handlebars from "handlebars";
export default registerUnbound(
"wizard-char-counter",
function (body, maxLength) {
let bodyLength = body ? body.length : 0;
let finalString;
if (maxLength) {
let isOverMax = bodyLength > maxLength ? "true" : "false";
finalString = `<div class="body-length" data-length=${bodyLength} data-over-max=${isOverMax}>${bodyLength} / ${I18n.t(
"wizard.x_characters",
{ count: parseInt(maxLength, 10) }
)}</div>`;
} else {
finalString = `<div class="body-length">${I18n.t("wizard.x_characters", {
count: parseInt(bodyLength, 10),
})}</div>`;
}
return new Handlebars.SafeString(finalString);
}
);

Datei anzeigen

@ -72,7 +72,7 @@ export default EmberObject.extend(ValidState, {
valid = true;
}
this.setValid(valid);
this.setValid(Boolean(valid));
return valid;
},

Datei anzeigen

@ -1,11 +1,11 @@
{{input
type=inputType
<Input
@type={{this.inputType}}
@value={{readonly this.value}}
class="date-picker"
placeholder=placeholder
value=(readonly value)
input=(action "onChangeDate")
tabindex=tabindex
placeholder={{this.placeholder}}
tabindex={{this.tabindex}}
{{on "input" (action "onChangeDate")}}
autocomplete="off"
}}
/>
<div class="picker-container"></div>

Datei anzeigen

@ -1,5 +1,6 @@
{{custom-wizard-category-selector
categories=categories
class=fieldClass
whitelist=field.content
onChange=(action (mut categories))
tabindex=field.tabindex

Datei anzeigen

@ -1 +1,7 @@
{{input type="checkbox" id=field.id checked=field.value tabindex=field.tabindex}}
<Input
id={{this.field.id}}
@type="checkbox"
@checked={{this.field.value}}
tabindex={{this.field.tabindex}}
class={{this.fieldClass}}
/>

Datei anzeigen

@ -2,6 +2,7 @@
field=field
composer=composer
wizard=wizard
fieldClass=fieldClass
groupsMentioned=(action "groupsMentioned")
cannotSeeMention=(action "cannotSeeMention")
importQuote=(action "importQuote")

Datei anzeigen

@ -1,5 +1,6 @@
{{custom-wizard-group-selector
groups=site.groups
class=fieldClass
field=field
whitelist=field.content
value=field.value

Datei anzeigen

@ -1 +1,9 @@
{{input type="number" step="0.01" id=field.id value=field.value tabindex=field.tabindex}}
<Input
id={{this.field.id}}
step="0.01"
@type="number"
@value={{this.field.value}}
tabindex={{this.field.tabindex}}
class={{this.fieldClass}}
/>

Datei anzeigen

@ -1,5 +1,6 @@
{{custom-wizard-tag-chooser
tags=field.value
class=fieldClass
tabindex=field.tabindex
tagGroups=field.tag_groups
everyTag=true

Datei anzeigen

@ -1 +1,8 @@
{{input id=field.id value=field.value class=fieldClass placeholder=field.translatedPlaceholder tabindex=field.tabindex autocomplete=autocomplete}}
<Input
id={{this.field.id}}
@value={{this.field.value}}
tabindex={{this.field.tabindex}}
class={{this.fieldClass}}
placeholder={{this.field.translatedPlaceholder}}
autocomplete={{this.autocomplete}}
/>

Datei anzeigen

@ -1 +1,7 @@
{{textarea id=field.id value=field.value class=fieldClass placeholder=field.translatedPlaceholder tabindex=field.tabindex}}
<Textarea
id={{this.field.id}}
@value={{this.field.value}}
tabindex={{this.field.tabindex}}
class={{this.fieldClass}}
placeholder={{this.field.translatedPlaceholder}}
/>

Datei anzeigen

@ -1 +1,6 @@
{{input type="text" id=field.id value=field.value tabindex=field.tabindex}}
<Input
id={{this.field.id}}
@value={{this.field.value}}
tabindex={{this.field.tabindex}}
class={{this.fieldClass}}
/>

Datei anzeigen

@ -20,7 +20,7 @@
{{#if field.char_counter}}
{{#if textType}}
{{char-counter field.value field.max_length}}
{{wizard-char-counter field.value field.max_length}}
{{/if}}
{{/if}}

Datei anzeigen

@ -716,7 +716,7 @@
property="name"
onUpdate=(action "mappedFieldUpdated")
options=(hash
textSelection="key,value"
textSelection="key,value,output"
wizardFieldSelection=true
userFieldSelection="key,value"
context="action"

Datei anzeigen

@ -32,13 +32,8 @@ body.custom-wizard {
}
}
&.invalid {
textarea,
input[type="text"],
input[type="checkbox"],
.select-kit {
outline: 4px solid var(--danger);
}
&.invalid .wizard-focusable {
outline: 4px solid var(--danger);
}
}

Datei anzeigen

@ -44,7 +44,7 @@ class CustomWizard::Mapper
def initialize(params)
@inputs = params[:inputs] || {}
@data = params[:data] || {}
@data = params[:data] ? params[:data].with_indifferent_access : {}
@user = params[:user]
@opts = params[:opts] || {}
end
@ -267,7 +267,12 @@ class CustomWizard::Mapper
return nil if data.nil?
k = keys.shift
result = data[k]
keys.empty? ? result : self.recurse(result, keys)
if keys.empty?
result.is_a?(Hash) ? "" : result
else
self.recurse(result, keys)
end
end
def bool(value)

Datei anzeigen

@ -84,6 +84,10 @@ class CustomWizard::Submission
data
end
def submitted?
!!submitted_at
end
def self.get(wizard)
data = PluginStore.get("#{wizard.id}_#{KEY}", wizard.actor_id).last
new(wizard, data)

Datei anzeigen

@ -176,6 +176,7 @@ class CustomWizard::Wizard
def unfinished?
return nil unless actor_id
return false if last_submission&.submitted?
most_recent = CustomWizard::UserHistory.where(
actor_id: actor_id,
@ -194,6 +195,7 @@ class CustomWizard::Wizard
def completed?
return nil unless actor_id
return true if last_submission&.submitted?
history = CustomWizard::UserHistory.where(
actor_id: actor_id,
@ -282,6 +284,10 @@ class CustomWizard::Wizard
@submissions ||= CustomWizard::Submission.list(self).submissions
end
def last_submission
@last_submission ||= submissions&.last
end
def current_submission
@current_submission ||= begin
if submissions.present?

Datei anzeigen

@ -58,6 +58,11 @@ describe CustomWizard::Mapper do
"step_1_field_3" => "Value"
}
}
let(:template_params_object) {
{
"step_1_field_1": get_wizard_fixture("field/upload")
}
}
def create_template_mapper(data, user)
CustomWizard::Mapper.new(
@ -448,6 +453,40 @@ describe CustomWizard::Mapper do
expect(result).to eq(template)
end
it "handles correct object variable references" do
template = <<-LIQUID.strip
{%- if "w{step_1_field_1.id}" == "step_2_field_7" -%}
Correct
{%- else -%}
Incorrect
{%-endif-%}
LIQUID
mapper = create_template_mapper(template_params_object, user1)
result = mapper.interpolate(
template.dup,
template: true,
wizard: true
)
expect(result).to eq("Correct")
end
it "handles incorrect object variable references" do
template = <<-LIQUID.strip
{%- if "w{step_1_field_1}" == "step_2_field_7" -%}
Correct
{%- else -%}
Incorrect
{%-endif-%}
LIQUID
mapper = create_template_mapper(template_params_object, user1)
result = mapper.interpolate(
template.dup,
template: true,
wizard: true
)
expect(result).to eq("Incorrect")
end
context "custom filter: 'first_non_empty'" do
it "gives first non empty element from list" do
template = <<-LIQUID.strip

Datei anzeigen

@ -7,6 +7,7 @@ describe CustomWizard::Wizard do
let(:template_json) { get_wizard_fixture("wizard") }
let(:permitted_json) { get_wizard_fixture("wizard/permitted") }
let(:guests_permitted_json) { get_wizard_fixture("wizard/guests_permitted") }
let(:step_json) { get_wizard_fixture("step/step") }
before do
Group.refresh_automatic_group!(:trust_level_3)
@ -75,6 +76,28 @@ describe CustomWizard::Wizard do
expect(@wizard.start).to eq('step_2')
end
it "determines the user's current step if steps are added" do
append_steps
progress_step('step_1')
progress_step('step_2')
progress_step("step_3")
fourth_step = step_json.dup
fourth_step['id'] = "step_4"
template = template_json.dup
template['steps'] << fourth_step
CustomWizard::Template.save(template, skip_jobs: true)
wizard = CustomWizard::Wizard.new(template, user)
template['steps'].each do |step_template|
wizard.append_step(step_template['id'])
end
expect(wizard.steps.size).to eq(4)
expect(wizard.start).to eq(nil)
end
it "creates a step updater" do
expect(
@wizard.create_updater('step_1', step_1_field_1: "Text input")