Improve validation for polls and improve builder (#12745)

* FIX: Show date picker over modal

Previously, scrolling was necessary to see the whole picker.

* FEATURE: Improve validation for polls

Adds new error messages for each of the edge cases. Previously, it
failed with a simple error saying that the minimum value must be less
than the maximum value.

* UX: Copy edit
This commit is contained in:
Bianca Nenciu 2021-04-22 21:36:32 +03:00 committed by GitHub
parent 139ba69117
commit 6c5d6dd356
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 92 additions and 61 deletions

View File

@ -6,4 +6,6 @@
input=(action "onChangeDate")
}}
<div class="picker-container"></div>
{{#unless useGlobalPickerContainer}}
<div class="picker-container"></div>
{{/unless}}

View File

@ -3,6 +3,7 @@
date=date
relativeDate=relativeDate
onChange=(action "onChangeDate")
useGlobalPickerContainer=useGlobalPickerContainer
}}
{{/unless}}
@ -19,6 +20,7 @@
date=date
relativeDate=relativeDate
onChange=(action "onChangeDate")
useGlobalPickerContainer=useGlobalPickerContainer
}}
{{/if}}

View File

@ -430,8 +430,7 @@
max-width: 420px;
}
.change-timestamp,
.poll-ui-builder {
.change-timestamp {
#date-container {
.pika-single {
position: relative !important; // overriding another important

View File

@ -116,6 +116,7 @@ export default Controller.extend(ModalFunctionality, {
_setPollMinMax() {
if (this.isMultiple) {
if (
this.pollMin <= 0 ||
this.pollMin >= this.pollMax ||
this.pollMin >= this.pollOptionsCount
) {
@ -123,10 +124,11 @@ export default Controller.extend(ModalFunctionality, {
}
if (
this.pollMax <= 0 ||
this.pollMin >= this.pollMax ||
this.pollMax > this.pollOptionsCount
) {
this.set("pollMax", Math.min(this.pollMin + 1, this.pollOptionsCount));
this.set("pollMax", this.pollOptionsCount);
}
} else if (this.isNumber) {
this.set("pollMax", this.siteSettings.poll_maximum_options);
@ -226,11 +228,22 @@ export default Controller.extend(ModalFunctionality, {
minNumOfOptionsValidation(isNumber, pollOptionsCount) {
let options = { ok: true };
if (!isNumber && pollOptionsCount === 0) {
options = {
failed: true,
reason: I18n.t("poll.ui_builder.help.options_count"),
};
if (!isNumber) {
if (pollOptionsCount < 1) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.options_min_count"),
});
}
if (pollOptionsCount > this.siteSettings.poll_maximum_options) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.options_max_count", {
count: this.siteSettings.poll_maximum_options,
}),
});
}
}
return EmberObject.create(options);
@ -246,69 +259,75 @@ export default Controller.extend(ModalFunctionality, {
"pollOptionsCount",
"isNumber",
"pollMin",
"pollMax"
"pollMax",
"pollStep"
)
minMaxValueValidation(
isMultiple,
pollOptionsCount,
isNumber,
pollMin,
pollMax
pollMax,
pollStep
) {
pollMin = parseInt(pollMin, 10) || 0;
pollMax = parseInt(pollMax, 10) || 0;
pollStep = parseInt(pollStep, 10) || 0;
const fail = {
failed: true,
reason: I18n.t("poll.ui_builder.help.invalid_values"),
};
if (pollMin < 0) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.invalid_min_value"),
});
}
if (isMultiple) {
if (
pollMin > pollMax ||
pollMin < 0 ||
(pollOptionsCount > 0 && pollMax > pollOptionsCount)
) {
return EmberObject.create(fail);
if (pollMax < 0 || (isMultiple && pollMax > pollOptionsCount)) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.invalid_max_value"),
});
}
if (pollMin > pollMax) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.invalid_values"),
});
}
if (isNumber) {
if (pollStep < 1) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.min_step_value"),
});
}
} else if (isNumber) {
if (pollMin >= pollMax) {
return EmberObject.create(fail);
const optionsCount = (pollMax - pollMin + 1) / pollStep;
if (optionsCount < 1) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.options_min_count"),
});
}
if (optionsCount > this.siteSettings.poll_maximum_options) {
return EmberObject.create({
failed: true,
reason: I18n.t("poll.ui_builder.help.options_max_count", {
count: this.siteSettings.poll_maximum_options,
}),
});
}
}
return EmberObject.create({ ok: true });
},
@discourseComputed("isNumber", "pollStep")
minStepValueValidation(isNumber, pollStep) {
let options = { ok: true };
if (isNumber && pollStep < 1) {
options = {
failed: true,
reason: I18n.t("poll.ui_builder.help.min_step_value"),
};
}
return EmberObject.create(options);
},
@discourseComputed(
"minMaxValueValidation",
"minStepValueValidation",
"minNumOfOptionsValidation"
)
disableInsert(
minMaxValueValidation,
minStepValueValidation,
minNumOfOptionsValidation
) {
return (
!minMaxValueValidation.ok ||
!minStepValueValidation.ok ||
!minNumOfOptionsValidation.ok
);
@discourseComputed("minMaxValueValidation", "minNumOfOptionsValidation")
disableInsert(minMaxValueValidation, minNumOfOptionsValidation) {
return !minMaxValueValidation.ok || !minNumOfOptionsValidation.ok;
},
_comboboxOptions(startIndex, endIndex) {

View File

@ -53,7 +53,8 @@
{{input type="number"
value=pollMin
valueProperty="value"
class="poll-options-min"}}
class="poll-options-min"
min=1}}
</div>
<div class="input-group poll-number">
@ -61,7 +62,8 @@
{{input type="number"
value=pollMax
valueProperty="value"
class="poll-options-max"}}
class="poll-options-max"
min=1}}
</div>
{{#if isNumber}}
@ -73,7 +75,6 @@
min="1"
class="poll-options-step"}}
</div>
{{input-tip validation=minStepValueValidation}}
{{/if}}
</div>
@ -95,7 +96,12 @@
<div class="input-group poll-date">
<label class="input-group-label">{{i18n "poll.ui_builder.automatic_close.label"}}</label>
{{date-time-input date=pollAutoClose onChange=(action (mut pollAutoClose)) clearable=true}}
{{date-time-input
date=pollAutoClose
onChange=(action (mut pollAutoClose))
clearable=true
useGlobalPickerContainer=true
}}
</div>
<div class="input-group poll-select">

View File

@ -86,7 +86,10 @@ en:
title: Build Poll
insert: Insert Poll
help:
options_count: Enter at least 1 option
options_min_count: Enter at least 1 option.
options_max_count: Enter at most %{count} options.
invalid_min_value: Minimum value must be at least 1.
invalid_max_value: Maximum value must be at least 1, but less than or equal with the number of options.
invalid_values: Minimum value must be smaller than the maximum value.
min_step_value: The minimum step value is 1
poll_type:
@ -107,8 +110,8 @@ en:
bar: Bar
pie: Pie
poll_config:
max: Max
min: Min
max: Max Choices
min: Min Choices
step: Step
poll_public:
label: Show who voted