DEV: Adopt modern ember primitives (#66)

Modernise components and controllers
This commit is contained in:
Selase Krakani 2022-11-22 12:30:03 +00:00 committed by GitHub
parent 7137499c69
commit a9d6614526
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 177 additions and 96 deletions

1
.discourse-compatibility Normal file
View File

@ -0,0 +1 @@
2.8.11: 7137499c69065928c0fdd8795a3fb8d175e1ff3d

View File

@ -1 +1 @@
{{show-user-notes show=(action "showUserNotes") count=userNotesCount}} <ShowUserNotes @show={{action "showUserNotes"}} @count={{this.userNotesCount}} />

View File

@ -1,5 +1,5 @@
{{#if userNotesCount}} {{#if userNotesCount}}
<a href {{action "showUserNotes"}} title={{userNotesTitle}}> <DButton @class="btn btn-flat" @translatedTitle={{userNotesTitle}} @action={{action "showUserNotes"}}>
{{#if emojiEnabled}} {{#if emojiEnabled}}
<img <img
src={{emojiUrl}} src={{emojiUrl}}
@ -10,5 +10,5 @@
{{else}} {{else}}
{{d-icon "sticky-note"}} {{d-icon "sticky-note"}}
{{/if}} {{/if}}
</a> </DButton>
{{/if}} {{/if}}

View File

@ -1,5 +1,5 @@
{{#if userNotesCount}} {{#if userNotesCount}}
<a href {{action "showUserNotes"}} title={{userNotesTitle}}> <DButton @class="btn btn-flat" @translatedTitle={{userNotesTitle}} @action={{action "showUserNotes"}}>
{{#if emojiEnabled}} {{#if emojiEnabled}}
<img <img
src={{emojiUrl}} src={{emojiUrl}}
@ -10,5 +10,5 @@
{{else}} {{else}}
{{d-icon "sticky-note"}} {{d-icon "sticky-note"}}
{{/if}} {{/if}}
</a> </DButton>
{{/if}} {{/if}}

View File

@ -1 +1 @@
{{show-user-notes show=(action "showUserNotes") count=userNotesCount}} <ShowUserNotes @show={{action "showUserNotes"}} @count={{this.userNotesCount}} />

View File

@ -0,0 +1,6 @@
<DButton
@class="btn btn-default"
@action={{@show}}
@icon="pencil-alt"
@translatedLabel={{this.label}}
/>

View File

@ -1,8 +1,12 @@
import Component from "@ember/component"; import Component from "@glimmer/component";
import { gt } from "@ember/object/computed"; import I18n from "I18n";
export default Component.extend({ export default class ShowUserNotes extends Component {
tagName: "", get label() {
if (this.args.count > 0) {
showCount: gt("count", 0), return I18n.t("user_notes.show", { count: this.args.count });
}); } else {
return I18n.t("user_notes.title");
}
}
}

View File

@ -1,70 +1,74 @@
import I18n from "I18n";
import discourseComputed, { on } from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n";
import { action } from "@ember/object";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { tracked } from "@glimmer/tracking";
export default Controller.extend({ export default class UserNotesController extends Controller {
dialog: service(), @service dialog;
newNote: null,
saving: false,
user: null,
@on("init") @tracked newNote;
reset() { @tracked userId;
this.setProperties({ newNote: null, saving: false, callback: null }); @tracked saving = false;
},
@discourseComputed("newNote", "saving") #refreshCount() {
attachDisabled(newNote, saving) {
return saving || !newNote || newNote.length === 0;
},
_refreshCount() {
if (this.callback) { if (this.callback) {
this.callback(this.get("model.length")); this.callback(this.model.length);
} }
}, }
actions: { reset() {
attachNote() { this.newNote = null;
const note = this.store.createRecord("user-note"); this.userId = null;
const userId = parseInt(this.userId, 10); this.callback = null;
this.saving = false;
}
this.set("saving", true); get attachDisabled() {
let args = { return this.saving || !this.newNote || this.newNote.length === 0;
raw: this.newNote, }
user_id: userId,
};
if (this.postId) { @action
args.post_id = parseInt(this.postId, 10); attachNote() {
} const note = this.store.createRecord("user-note");
const userId = parseInt(this.userId, 10);
note this.saving = true;
.save(args)
.then(() => {
this.set("newNote", "");
this.model.insertAt(0, note);
this._refreshCount();
})
.catch(popupAjaxError)
.finally(() => this.set("saving", false));
},
removeNote(note) { const args = {
this.dialog.deleteConfirm({ raw: this.newNote,
message: I18n.t("user_notes.delete_confirm"), user_id: userId,
didConfirm: () => { };
note
.destroyRecord() if (this.postId) {
.then(() => { args.post_id = parseInt(this.postId, 10);
this.model.removeObject(note); }
this._refreshCount();
}) note
.catch(popupAjaxError); .save(args)
}, .then(() => {
}); this.newNote = "";
}, this.model.insertAt(0, note);
}, this.#refreshCount();
}); })
.catch(popupAjaxError)
.finally(() => (this.saving = false));
}
@action
removeNote(note) {
this.dialog.deleteConfirm({
message: I18n.t("user_notes.delete_confirm"),
didConfirm: () => {
note
.destroyRecord()
.then(() => {
this.model.removeObject(note);
this.#refreshCount();
})
.catch(popupAjaxError);
},
});
}
}

View File

@ -1,8 +0,0 @@
<a {{action show}} href class="btn btn-default">
{{d-icon "pencil-alt"}}
{{#if showCount}}
{{i18n "user_notes.show" count=count}}
{{else}}
{{i18n "user_notes.title"}}
{{/if}}
</a>

View File

@ -1,18 +1,18 @@
{{#d-modal-body class="user-notes-modal"}} <DModalBody @class="user-notes-modal">
{{textarea value=newNote}} <Textarea @value={{this.newNote}} />
{{d-button <DButton
action=(action "attachNote") @action={{action "attachNote"}}
label="user_notes.attach" @label="user_notes.attach"
class="btn-primary" @class="btn-primary"
disabled=attachDisabled @disabled={{this.attachDisabled}}
}} />
{{#each model as |n|}} {{#each model as |n|}}
<div class="user-note"> <div class="user-note">
<div class="posted-by"> <div class="posted-by">
{{#user-link user=n.created_by}} <UserLink @user={{n.created_by}}>
{{avatar n.created_by imageSize="small"}} {{avatar n.created_by imageSize="small"}}
{{/user-link}} </UserLink>
</div> </div>
<div class="note-contents"> <div class="note-contents">
<div class="note-info"> <div class="note-info">
@ -21,12 +21,12 @@
{{#if n.can_delete}} {{#if n.can_delete}}
<span class="controls"> <span class="controls">
{{d-button <DButton
action=(action "removeNote" n) @action={{action "removeNote" n}}
icon="far-trash-alt" @icon="far-trash-alt"
class="btn-small btn-danger" @class="btn-small btn-danger"
title="user_notes.remove" @title="user_notes.remove"
}} />
</span> </span>
{{/if}} {{/if}}
</div> </div>
@ -45,4 +45,4 @@
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
{{/each}} {{/each}}
{{/d-modal-body}} </DModalBody>

View File

@ -6,6 +6,18 @@
.show-user-notes-on-flags { .show-user-notes-on-flags {
display: inline-block; display: inline-block;
button {
display: inline;
padding: 0;
}
}
.show-user-notes-on-card {
button {
display: inline;
padding: 0;
}
} }
.modal-body.user-notes-modal { .modal-body.user-notes-modal {

View File

@ -0,0 +1,62 @@
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { click, fillIn, visit } from "@ember/test-helpers";
import I18n from "I18n";
acceptance("User Notes", function (needs) {
needs.user();
needs.settings({ user_notes_enabled: true });
needs.pretender((server, helper) => {
server.get("/user_notes", () => {
return helper.response(200, {
extras: { username: "eviltrout" },
user_notes: [],
});
});
server.post("/user_notes", () => {
return helper.response(200, {
user_note: {
id: "6d945d25740e9801920e54c71c516c7b",
user_id: 1,
raw: "Helpful user",
created_by: {
id: 2,
username: "sam",
name: null,
avatar_template:
"/letter_avatar_proxy/v4/letter/s/ac8455/{size}.png",
},
created_at: "2022-11-16T22:00:00.000Z",
can_delete: true,
post_id: null,
post_url: "",
post_title: null,
},
});
});
});
test("creates note from user's profile", async function (assert) {
await visit("/admin/users/1/eviltrout");
assert.dom(".user-controls button").hasText(I18n.t("user_notes.title"));
assert.dom(".user-notes-modal.modal-body").isNotVisible();
await click(".user-controls button");
assert.dom(".user-notes-modal.modal-body").isVisible();
await fillIn(".user-notes-modal textarea", "Helpful user");
assert.dom(".user-notes-modal.modal-body button").isEnabled();
await click(".user-notes-modal.modal-body button");
await click(".user-notes-modal button.modal-close");
assert
.dom(".user-controls button")
.hasText(I18n.t("user_notes.show", { count: 1 }));
});
});