REFACTOR: admin-user-field-item (#16499)
- drops jquery - removes a deprecation caused by overriding a computed property (isEditing) - adds basic tests - drops observers - uses @action - tagless
This commit is contained in:
parent
137e06a316
commit
01727da9b0
|
@ -1,20 +1,17 @@
|
||||||
import discourseComputed, {
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
observes,
|
|
||||||
on,
|
|
||||||
} from "discourse-common/utils/decorators";
|
|
||||||
import { i18n, propertyEqual } from "discourse/lib/computed";
|
import { i18n, propertyEqual } from "discourse/lib/computed";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import UserField from "admin/models/user-field";
|
import UserField from "admin/models/user-field";
|
||||||
import { bufferedProperty } from "discourse/mixins/buffered-content";
|
import { bufferedProperty } from "discourse/mixins/buffered-content";
|
||||||
import { empty } from "@ember/object/computed";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import { scheduleOnce } from "@ember/runloop";
|
import { schedule } from "@ember/runloop";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
|
||||||
export default Component.extend(bufferedProperty("userField"), {
|
export default Component.extend(bufferedProperty("userField"), {
|
||||||
editing: empty("userField.id"),
|
tagName: "",
|
||||||
classNameBindings: [":user-field"],
|
isEditing: false,
|
||||||
|
|
||||||
cantMoveUp: propertyEqual("userField", "firstField"),
|
cantMoveUp: propertyEqual("userField", "firstField"),
|
||||||
cantMoveDown: propertyEqual("userField", "lastField"),
|
cantMoveDown: propertyEqual("userField", "lastField"),
|
||||||
|
@ -26,21 +23,21 @@ export default Component.extend(bufferedProperty("userField"), {
|
||||||
return UserField.fieldTypeById(fieldType);
|
return UserField.fieldTypeById(fieldType);
|
||||||
},
|
},
|
||||||
|
|
||||||
@on("didInsertElement")
|
didInsertElement() {
|
||||||
@observes("editing")
|
this._super(...arguments);
|
||||||
_focusOnEdit() {
|
|
||||||
if (this.editing) {
|
this._focusName();
|
||||||
scheduleOnce("afterRender", this, "_focusName");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_focusName() {
|
_focusName() {
|
||||||
$(".user-field-name").select();
|
schedule("afterRender", () => {
|
||||||
|
document.querySelector(".user-field-name")?.focus();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed("userField.field_type")
|
@discourseComputed("userField.field_type")
|
||||||
fieldName(fieldType) {
|
fieldName(fieldType) {
|
||||||
return UserField.fieldTypeById(fieldType).get("name");
|
return UserField.fieldTypeById(fieldType)?.name;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed(
|
@discourseComputed(
|
||||||
|
@ -67,10 +64,9 @@ export default Component.extend(bufferedProperty("userField"), {
|
||||||
return ret.join(", ");
|
return ret.join(", ");
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
@action
|
||||||
save() {
|
save() {
|
||||||
const buffered = this.buffered;
|
const attrs = this.buffered.getProperties(
|
||||||
const attrs = buffered.getProperties(
|
|
||||||
"name",
|
"name",
|
||||||
"description",
|
"description",
|
||||||
"field_type",
|
"field_type",
|
||||||
|
@ -82,27 +78,32 @@ export default Component.extend(bufferedProperty("userField"), {
|
||||||
"options"
|
"options"
|
||||||
);
|
);
|
||||||
|
|
||||||
this.userField
|
return this.userField
|
||||||
.save(attrs)
|
.save(attrs)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.set("editing", false);
|
if (this.isDestroying || this.isDestroyed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set("isEditing", false);
|
||||||
this.commitBuffer();
|
this.commitBuffer();
|
||||||
})
|
})
|
||||||
.catch(popupAjaxError);
|
.catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
edit() {
|
edit() {
|
||||||
this.set("editing", true);
|
this.set("isEditing", true);
|
||||||
|
this._focusName();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@action
|
||||||
cancel() {
|
cancel() {
|
||||||
const id = this.get("userField.id");
|
if (isEmpty(this.userField?.id)) {
|
||||||
if (isEmpty(id)) {
|
|
||||||
this.destroyAction(this.userField);
|
this.destroyAction(this.userField);
|
||||||
} else {
|
} else {
|
||||||
this.rollbackBuffer();
|
this.rollbackBuffer();
|
||||||
this.set("editing", false);
|
this.set("isEditing", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{{#if editing}}
|
<div class="user-field">
|
||||||
|
{{#if (or isEditing (not userField.id))}}
|
||||||
{{#admin-form-row label="admin.user_fields.type"}}
|
{{#admin-form-row label="admin.user_fields.type"}}
|
||||||
{{combo-box
|
{{combo-box
|
||||||
content=fieldTypes
|
content=fieldTypes
|
||||||
|
@ -42,24 +43,24 @@
|
||||||
{{/admin-form-row}}
|
{{/admin-form-row}}
|
||||||
|
|
||||||
{{#admin-form-row}}
|
{{#admin-form-row}}
|
||||||
{{d-button action=(action "save") class="btn-primary" icon="check" label="admin.user_fields.save"}}
|
{{d-button action=(action "save") class="btn-primary save" icon="check" label="admin.user_fields.save"}}
|
||||||
{{d-button action=(action "cancel") class="btn-danger" icon="times" label="admin.user_fields.cancel"}}
|
{{d-button action=(action "cancel") class="btn-danger cancel" icon="times" label="admin.user_fields.cancel"}}
|
||||||
{{/admin-form-row}}
|
{{/admin-form-row}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-display">
|
<div class="form-display">
|
||||||
<strong>{{userField.name}}</strong>
|
<b class="name">{{userField.name}}</b>
|
||||||
<br>
|
<br>
|
||||||
{{html-safe userField.description}}
|
<span class="description">{{html-safe userField.description}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-display">{{fieldName}}</div>
|
<div class="form-display field-type">{{fieldName}}</div>
|
||||||
<div class="form-element controls">
|
<div class="form-element controls">
|
||||||
{{d-button action=(action "edit") class="btn-default" icon="pencil-alt" label="admin.user_fields.edit"}}
|
{{d-button action=(action "edit") class="btn-default edit" icon="pencil-alt" label="admin.user_fields.edit"}}
|
||||||
{{d-button action=destroyAction actionParam=userField class="btn-danger" icon="far-trash-alt" label="admin.user_fields.delete"}}
|
{{d-button action=destroyAction actionParam=userField class="btn-danger cancel" icon="far-trash-alt" label="admin.user_fields.delete"}}
|
||||||
{{d-button action=moveUpAction actionParam=userField class="btn-default" icon="arrow-up" disabled=cantMoveUp}}
|
{{d-button action=moveUpAction actionParam=userField class="btn-default" icon="arrow-up" disabled=cantMoveUp}}
|
||||||
{{d-button action=moveDownAction actionParam=userField class="btn-default" icon="arrow-down" disabled=cantMoveDown}}
|
{{d-button action=moveDownAction actionParam=userField class="btn-default" icon="arrow-down" disabled=cantMoveDown}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">{{flags}}</div>
|
<div class="row">{{flags}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="clearfix"></div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import componentTest, {
|
||||||
|
setupRenderingTest,
|
||||||
|
} from "discourse/tests/helpers/component-test";
|
||||||
|
import {
|
||||||
|
discourseModule,
|
||||||
|
exists,
|
||||||
|
query,
|
||||||
|
} from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
import hbs from "htmlbars-inline-precompile";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import { click } from "@ember/test-helpers";
|
||||||
|
|
||||||
|
discourseModule(
|
||||||
|
"Integration | Component | admin-user-field-item",
|
||||||
|
function (hooks) {
|
||||||
|
setupRenderingTest(hooks);
|
||||||
|
|
||||||
|
componentTest("user field without an id", {
|
||||||
|
template: hbs`{{admin-user-field-item userField=userField}}`,
|
||||||
|
|
||||||
|
async test(assert) {
|
||||||
|
assert.ok(exists(".save"), "displays editing mode");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
componentTest("cancel action", {
|
||||||
|
template: hbs`{{admin-user-field-item isEditing=isEditing destroyAction=destroyAction userField=userField}}`,
|
||||||
|
|
||||||
|
beforeEach() {
|
||||||
|
this.set("userField", { id: 1, field_type: "text" });
|
||||||
|
this.set("isEditing", true);
|
||||||
|
},
|
||||||
|
|
||||||
|
async test(assert) {
|
||||||
|
await click(".cancel");
|
||||||
|
assert.ok(exists(".edit"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
componentTest("edit action", {
|
||||||
|
template: hbs`{{admin-user-field-item destroyAction=destroyAction userField=userField}}`,
|
||||||
|
|
||||||
|
beforeEach() {
|
||||||
|
this.set("userField", { id: 1, field_type: "text" });
|
||||||
|
},
|
||||||
|
|
||||||
|
async test(assert) {
|
||||||
|
await click(".edit");
|
||||||
|
assert.ok(exists(".save"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
componentTest("user field with an id", {
|
||||||
|
template: hbs`{{admin-user-field-item userField=userField}}`,
|
||||||
|
|
||||||
|
beforeEach() {
|
||||||
|
this.set("userField", {
|
||||||
|
id: 1,
|
||||||
|
field_type: "text",
|
||||||
|
name: "foo",
|
||||||
|
description: "what is foo",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async test(assert) {
|
||||||
|
assert.equal(query(".name").innerText, this.userField.name);
|
||||||
|
assert.equal(
|
||||||
|
query(".description").innerText,
|
||||||
|
this.userField.description
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
query(".field-type").innerText,
|
||||||
|
I18n.t("admin.user_fields.field_types.text")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
Loading…
Reference in New Issue