mirror of
https://github.com/discourse/discourse.git
synced 2025-06-25 14:21:38 +08:00
FIX: ensures empty fields don't store an empty array (#33274)
This is a follow-up to
299d28cb73
to apply it to more fields.
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import { fn, hash } from "@ember/helper";
|
||||
import { hash } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import Category from "discourse/models/category";
|
||||
import CategorySelector from "select-kit/components/category-selector";
|
||||
import BaseField from "./da-base-field";
|
||||
@ -7,6 +8,16 @@ import DAFieldDescription from "./da-field-description";
|
||||
import DAFieldLabel from "./da-field-label";
|
||||
|
||||
export default class CategoriesField extends BaseField {
|
||||
@action
|
||||
onChangeCategories(categories) {
|
||||
if (isBlank(categories)) {
|
||||
this.mutValue(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
this.mutValue(categories.mapBy("id"));
|
||||
}
|
||||
|
||||
<template>
|
||||
{{! template-lint-disable no-redundant-fn }}
|
||||
<section class="field categories-field">
|
||||
@ -16,7 +27,7 @@ export default class CategoriesField extends BaseField {
|
||||
<div class="controls">
|
||||
<CategorySelector
|
||||
@categories={{this.categories}}
|
||||
@onChange={{fn this.onChangeCategories}}
|
||||
@onChange={{this.onChangeCategories}}
|
||||
@options={{hash clearable=true disabled=@field.isDisabled}}
|
||||
/>
|
||||
|
||||
@ -30,9 +41,4 @@ export default class CategoriesField extends BaseField {
|
||||
const ids = this.args.field?.metadata?.value || [];
|
||||
return ids.map((id) => Category.findById(id)).filter(Boolean);
|
||||
}
|
||||
|
||||
@action
|
||||
onChangeCategories(categories) {
|
||||
this.mutValue(categories.mapBy("id"));
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { hash } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import ComboBox from "select-kit/components/combo-box";
|
||||
import MultiSelect from "select-kit/components/multi-select";
|
||||
@ -7,6 +9,15 @@ import DAFieldDescription from "./da-field-description";
|
||||
import DAFieldLabel from "./da-field-label";
|
||||
|
||||
export default class ChoicesField extends BaseField {
|
||||
@action
|
||||
onChangeChoices(choices) {
|
||||
if (isBlank(choices)) {
|
||||
choices = undefined;
|
||||
}
|
||||
|
||||
this.mutValue(choices);
|
||||
}
|
||||
|
||||
<template>
|
||||
<div class="field control-group">
|
||||
<DAFieldLabel @label={{@label}} @field={{@field}} />
|
||||
@ -16,7 +27,7 @@ export default class ChoicesField extends BaseField {
|
||||
<MultiSelect
|
||||
@value={{@field.metadata.value}}
|
||||
@content={{this.replacedContent}}
|
||||
@onChange={{this.mutValue}}
|
||||
@onChange={{this.onChangeChoices}}
|
||||
@options={{hash
|
||||
allowAny=false
|
||||
clearable=true
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { hash } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import Group from "discourse/models/group";
|
||||
import GroupChooser from "select-kit/components/group-chooser";
|
||||
import BaseField from "./da-base-field";
|
||||
@ -30,6 +31,10 @@ export default class GroupsField extends BaseField {
|
||||
|
||||
@action
|
||||
setGroupField(groupIds) {
|
||||
if (isBlank(groupIds)) {
|
||||
groupIds = undefined;
|
||||
}
|
||||
|
||||
this.mutValue(groupIds);
|
||||
}
|
||||
|
||||
@ -41,7 +46,7 @@ export default class GroupsField extends BaseField {
|
||||
<div class="controls">
|
||||
<GroupChooser
|
||||
@content={{this.allGroups}}
|
||||
@value={{@field.metadata.value}}
|
||||
@value={{readonly @field.metadata.value}}
|
||||
@labelProperty="name"
|
||||
@onChange={{this.setGroupField}}
|
||||
@options={{hash maximum=this.maximum disabled=@field.isDisabled}}
|
||||
|
@ -10,7 +10,7 @@ export default class TagsField extends BaseField {
|
||||
@action
|
||||
onChangeTags(tags) {
|
||||
if (isBlank(tags)) {
|
||||
tags = undefined; // avoids storing [] as value which can complicate logic in the backend
|
||||
tags = undefined;
|
||||
}
|
||||
|
||||
this.mutValue(tags);
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import MultiSelect from "select-kit/components/multi-select";
|
||||
import BaseField from "./da-base-field";
|
||||
import DAFieldDescription from "./da-field-description";
|
||||
@ -7,6 +9,15 @@ import DAFieldLabel from "./da-field-label";
|
||||
export default class TrustLevelsField extends BaseField {
|
||||
@service site;
|
||||
|
||||
@action
|
||||
onChangeTrustLevels(value) {
|
||||
if (isBlank(value)) {
|
||||
value = undefined;
|
||||
}
|
||||
|
||||
this.mutValue(value);
|
||||
}
|
||||
|
||||
<template>
|
||||
<section class="field category-field">
|
||||
<div class="control-group">
|
||||
@ -16,7 +27,7 @@ export default class TrustLevelsField extends BaseField {
|
||||
<MultiSelect
|
||||
@value={{@field.metadata.value}}
|
||||
@content={{this.site.trustLevels}}
|
||||
@onChange={{this.mutValue}}
|
||||
@onChange={{this.onChangeTrustLevels}}
|
||||
/>
|
||||
|
||||
<DAFieldDescription @description={{@description}} />
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { hash } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { isBlank } from "@ember/utils";
|
||||
import UserChooser from "select-kit/components/user-chooser";
|
||||
import BaseField from "./da-base-field";
|
||||
import DAFieldDescription from "./da-field-description";
|
||||
import DAFieldLabel from "./da-field-label";
|
||||
|
||||
export default class UsersField extends BaseField {
|
||||
@action
|
||||
onChangeUsers(users) {
|
||||
if (isBlank(users)) {
|
||||
users = undefined;
|
||||
}
|
||||
|
||||
this.mutValue(users);
|
||||
}
|
||||
|
||||
<template>
|
||||
<section class="field users-field">
|
||||
<div class="control-group">
|
||||
@ -13,7 +24,7 @@ export default class UsersField extends BaseField {
|
||||
<div class="controls">
|
||||
<UserChooser
|
||||
@value={{@field.metadata.value}}
|
||||
@onChange={{this.mutValue}}
|
||||
@onChange={{this.onChangeUsers}}
|
||||
@options={{hash
|
||||
excludeCurrentUser=false
|
||||
disabled=@field.isDisabled
|
||||
|
@ -35,4 +35,30 @@ module("Integration | Component | da-categories-field", function (hooks) {
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, [6, 8]);
|
||||
});
|
||||
|
||||
test("empty", async function (assert) {
|
||||
const self = this;
|
||||
|
||||
this.field = new AutomationFabricators(getOwner(this)).field({
|
||||
component: "categories",
|
||||
});
|
||||
|
||||
await render(
|
||||
<template>
|
||||
<AutomationField
|
||||
@automation={{self.automation}}
|
||||
@field={{self.field}}
|
||||
/>
|
||||
</template>
|
||||
);
|
||||
|
||||
await selectKit().expand();
|
||||
await selectKit().selectRowByValue(6);
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, [6]);
|
||||
|
||||
await selectKit().deselectItemByValue(6);
|
||||
|
||||
assert.strictEqual(this.field.metadata.value, undefined);
|
||||
});
|
||||
});
|
||||
|
@ -35,4 +35,31 @@ module("Integration | Component | da-choices-field", function (hooks) {
|
||||
|
||||
assert.strictEqual(this.field.metadata.value, 1);
|
||||
});
|
||||
|
||||
test("empty multiselect", async function (assert) {
|
||||
const self = this;
|
||||
|
||||
this.field = new AutomationFabricators(getOwner(this)).field({
|
||||
component: "choices",
|
||||
extra: { multiselect: true, content: [{ name: "One", id: 1 }] },
|
||||
});
|
||||
|
||||
await render(
|
||||
<template>
|
||||
<AutomationField
|
||||
@automation={{self.automation}}
|
||||
@field={{self.field}}
|
||||
/>
|
||||
</template>
|
||||
);
|
||||
|
||||
await selectKit().expand();
|
||||
await selectKit().selectRowByValue(1);
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, [1]);
|
||||
|
||||
await selectKit().deselectItemByValue(1);
|
||||
|
||||
assert.strictEqual(this.field.metadata.value, undefined);
|
||||
});
|
||||
});
|
||||
|
@ -55,7 +55,7 @@ module("Integration | Component | da-groups-field", function (hooks) {
|
||||
assert.deepEqual(this.field.metadata.value, [1]);
|
||||
});
|
||||
|
||||
test("supports a maxmimum value", async function (assert) {
|
||||
test("supports a maximum value", async function (assert) {
|
||||
const self = this;
|
||||
|
||||
this.field = new AutomationFabricators(getOwner(this)).field({
|
||||
@ -82,4 +82,30 @@ module("Integration | Component | da-groups-field", function (hooks) {
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, [2]);
|
||||
});
|
||||
|
||||
test("empty", async function (assert) {
|
||||
const self = this;
|
||||
|
||||
this.field = new AutomationFabricators(getOwner(this)).field({
|
||||
component: "groups",
|
||||
});
|
||||
|
||||
await render(
|
||||
<template>
|
||||
<AutomationField
|
||||
@automation={{self.automation}}
|
||||
@field={{self.field}}
|
||||
/>
|
||||
</template>
|
||||
);
|
||||
|
||||
await selectKit().expand();
|
||||
await selectKit().selectRowByValue(1);
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, [1]);
|
||||
|
||||
await selectKit().deselectItemByValue(1);
|
||||
|
||||
assert.strictEqual(this.field.metadata.value, undefined);
|
||||
});
|
||||
});
|
||||
|
@ -57,6 +57,6 @@ module("Integration | Component | da-tags-field", function (hooks) {
|
||||
|
||||
await selectKit().deselectItemByValue("monkey");
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, undefined);
|
||||
assert.strictEqual(this.field.metadata.value, undefined);
|
||||
});
|
||||
});
|
||||
|
@ -35,4 +35,29 @@ module("Integration | Component | da-trust-levels-field", function (hooks) {
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, [1, 2]);
|
||||
});
|
||||
|
||||
test("empty", async function (assert) {
|
||||
const self = this;
|
||||
|
||||
this.field = new AutomationFabricators(getOwner(this)).field({
|
||||
component: "trust-levels",
|
||||
});
|
||||
|
||||
await render(
|
||||
<template>
|
||||
<AutomationField
|
||||
@automation={{self.automation}}
|
||||
@field={{self.field}}
|
||||
/>
|
||||
</template>
|
||||
);
|
||||
await selectKit().expand();
|
||||
await selectKit().selectRowByValue(1);
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, [1]);
|
||||
|
||||
await selectKit().deselectItemByValue(1);
|
||||
|
||||
assert.strictEqual(this.field.metadata.value, undefined);
|
||||
});
|
||||
});
|
||||
|
@ -78,4 +78,31 @@ module("Integration | Component | da-users-field", function (hooks) {
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, ["j.jaffeux@example.com"]);
|
||||
});
|
||||
|
||||
test("empty", async function (assert) {
|
||||
const self = this;
|
||||
|
||||
this.field = new AutomationFabricators(getOwner(this)).field({
|
||||
component: "users",
|
||||
});
|
||||
|
||||
await render(
|
||||
<template>
|
||||
<AutomationField
|
||||
@automation={{self.automation}}
|
||||
@field={{self.field}}
|
||||
/>
|
||||
</template>
|
||||
);
|
||||
|
||||
await selectKit().expand();
|
||||
await selectKit().fillInFilter("sam");
|
||||
await selectKit().selectRowByValue("sam");
|
||||
|
||||
assert.deepEqual(this.field.metadata.value, ["sam"]);
|
||||
|
||||
await selectKit().deselectItemByValue("sam");
|
||||
|
||||
assert.strictEqual(this.field.metadata.value, undefined);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user