DEV: Add validation message to integer fields in theme object editora (#26284)

Why this change?

This is a continuation of 8de869630f.

In our schema, we support the `min` and `max` validation
rules like so:

```
some_objects_setting
  type: objects
  schema:
    name: some_object
    properties:
      id:
        type: integer
        validations:
          min: 5
          max: 10
```

While the validations used to validate the objects on the server side,
we should also add client side validation for better UX.
This commit is contained in:
Alan Guo Xiang Tan
2024-03-21 15:03:07 +08:00
committed by GitHub
parent 8de869630f
commit a30d73f255
3 changed files with 131 additions and 25 deletions

View File

@@ -1,18 +1,80 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { Input } from "@ember/component";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { and, not } from "truth-helpers";
import I18n from "discourse-i18n";
import FieldInputDescription from "admin/components/schema-theme-setting/field-input-description";
export default class SchemaThemeSettingTypeInteger extends Component {
@tracked touched = false;
@tracked value = this.args.value;
min = this.args.spec.validations?.min;
max = this.args.spec.validations?.max;
required = this.args.spec.required;
@action
onInput(event) {
this.args.onChange(parseInt(event.currentTarget.value, 10));
this.touched = true;
let newValue = parseInt(event.currentTarget.value, 10);
if (isNaN(newValue)) {
newValue = null;
}
this.value = newValue;
this.args.onChange(newValue);
}
get validationErrorMessage() {
if (!this.touched) {
return;
}
if (!this.value) {
if (this.required) {
return I18n.t("admin.customize.theme.schema.fields.required");
} else {
return;
}
}
if (this.min && this.value < this.min) {
return I18n.t("admin.customize.theme.schema.fields.number.too_small", {
count: this.min,
});
}
if (this.max && this.value > this.max) {
return I18n.t("admin.customize.theme.schema.fields.number.too_large", {
count: this.max,
});
}
}
<template>
<Input @value={{@value}} {{on "input" this.onInput}} @type="number" />
<Input
@value={{this.value}}
{{on "input" this.onInput}}
@type="number"
inputmode="numeric"
pattern="[0-9]*"
max={{this.max}}
min={{this.min}}
required={{this.required}}
/>
<FieldInputDescription @description={{@description}} />
<div class="schema-field__input-supporting-text">
{{#if (and @description (not this.validationErrorMessage))}}
<FieldInputDescription @description={{@description}} />
{{/if}}
{{#if this.validationErrorMessage}}
<div class="schema-field__input-error">
{{this.validationErrorMessage}}
</div>
{{/if}}
</div>
</template>
}