DEV: Refactor Discourse models based field components to reduce duplication (#26452)

Why this change?

The field components to select categories, groups and tags had quite a
bit of logic duplicated between them. This commit refactors the logic
to remove most of the duplication so that we can introduce changes
without having to make the changes in multiple places.
This commit is contained in:
Alan Guo Xiang Tan 2024-04-02 09:32:50 +08:00 committed by GitHub
parent 3520f4a635
commit 397a1b7366
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 93 deletions

View File

@ -1,45 +1,21 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking"; import { tracked } from "@glimmer/tracking";
import { hash } from "@ember/helper"; import { hash } from "@ember/helper";
import { action } from "@ember/object";
import { and, not } from "truth-helpers"; import { and, not } from "truth-helpers";
import I18n from "discourse-i18n";
import FieldInputDescription from "admin/components/schema-theme-setting/field-input-description"; import FieldInputDescription from "admin/components/schema-theme-setting/field-input-description";
import SchemaThemeSettingTypeModels from "admin/components/schema-theme-setting/types/models";
import CategorySelector from "select-kit/components/category-selector"; import CategorySelector from "select-kit/components/category-selector";
export default class SchemaThemeSettingTypeCategories extends Component { export default class SchemaThemeSettingTypeCategories extends SchemaThemeSettingTypeModels {
@tracked touched = false;
@tracked @tracked
value = value =
this.args.value?.map((categoryId) => { this.args.value?.map((categoryId) => {
return this.args.setting.metadata.categories[categoryId]; return this.args.setting.metadata.categories[categoryId];
}) || []; }) || [];
required = this.args.spec.required; type = "categories";
min = this.args.spec.validations?.min;
max = this.args.spec.validations?.max;
@action onChange(categories) {
onInput(categories) { return categories.mapBy("id");
this.touched = true;
this.value = categories;
this.args.onChange(categories.map((category) => category.id));
}
get validationErrorMessage() {
if (!this.touched) {
return;
}
if (
(this.min && this.value.length < this.min) ||
(this.required && (!this.value || this.value.length === 0))
) {
return I18n.t("admin.customize.theme.schema.fields.categories.at_least", {
count: this.min || 1,
});
}
} }
<template> <template>

View File

@ -1,42 +1,13 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { service } from "@ember/service"; import { service } from "@ember/service";
import { and, not } from "truth-helpers"; import { and, not } from "truth-helpers";
import I18n from "discourse-i18n";
import FieldInputDescription from "admin/components/schema-theme-setting/field-input-description"; import FieldInputDescription from "admin/components/schema-theme-setting/field-input-description";
import SchemaThemeSettingTypeModels from "admin/components/schema-theme-setting/types/models";
import GroupChooser from "select-kit/components/group-chooser"; import GroupChooser from "select-kit/components/group-chooser";
export default class SchemaThemeSettingTypeGroups extends Component { export default class SchemaThemeSettingTypeGroups extends SchemaThemeSettingTypeModels {
@service site; @service site;
@tracked touched = false;
@tracked value = this.args.value;
required = this.args.spec.required; type = "groups";
min = this.args.spec.validations?.min;
max = this.args.spec.validations?.max;
@action
onInput(newVal) {
this.touched = true;
this.value = newVal;
this.args.onChange(newVal);
}
get validationErrorMessage() {
if (!this.touched) {
return;
}
if (
(this.min && this.value.length < this.min) ||
(this.required && (!this.value || this.value.length === 0))
) {
return I18n.t("admin.customize.theme.schema.fields.groups.at_least", {
count: this.min || 1,
});
}
}
get groupChooserOptions() { get groupChooserOptions() {
return { return {

View File

@ -0,0 +1,44 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { isBlank } from "@ember/utils";
import I18n from "discourse-i18n";
export default class SchemaThemeSettingTypeModels extends Component {
@tracked touched = false;
@tracked value = this.args.value;
required = this.args.spec.required;
min = this.args.spec.validations?.min;
max = this.args.spec.validations?.max;
type;
@action
onInput(newValue) {
this.touched = true;
this.value = newValue;
this.args.onChange(this.onChange(newValue));
}
onChange(newValue) {
return newValue;
}
get validationErrorMessage() {
if (!this.touched) {
return;
}
if (
(this.min && this.value.length < this.min) ||
(this.required && isBlank(this.value))
) {
return I18n.t(
`admin.customize.theme.schema.fields.${this.type}.at_least`,
{
count: this.min || 1,
}
);
}
}
}

View File

@ -1,24 +1,10 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { and, not } from "truth-helpers"; import { and, not } from "truth-helpers";
import I18n from "discourse-i18n";
import FieldInputDescription from "admin/components/schema-theme-setting/field-input-description"; import FieldInputDescription from "admin/components/schema-theme-setting/field-input-description";
import SchemaThemeSettingTypeModels from "admin/components/schema-theme-setting/types/models";
import TagChooser from "select-kit/components/tag-chooser"; import TagChooser from "select-kit/components/tag-chooser";
export default class SchemaThemeSettingTypeTags extends Component { export default class SchemaThemeSettingTypeTags extends SchemaThemeSettingTypeModels {
@tracked touched = false; type = "tags";
@tracked value = this.args.value;
required = this.args.spec.required;
min = this.args.spec.validations?.min;
max = this.args.spec.validations?.max;
@action
onInput(newVal) {
this.touched = true;
this.value = newVal;
this.args.onChange(newVal);
}
get tagChooserOption() { get tagChooserOption() {
return { return {
@ -27,21 +13,6 @@ export default class SchemaThemeSettingTypeTags extends Component {
}; };
} }
get validationErrorMessage() {
if (!this.touched) {
return;
}
if (
(this.min && this.value.length < this.min) ||
(this.required && (!this.value || this.value.length === 0))
) {
return I18n.t("admin.customize.theme.schema.fields.tags.at_least", {
count: this.min || 1,
});
}
}
<template> <template>
<TagChooser <TagChooser
@tags={{this.value}} @tags={{this.value}}