DEV: Convert ChangePostNoticeModal to DModal and Glimmer component (#22798)

This PR converts the post notice modal from the old template + controller to a modern Glimmer + DModal component.

In addition to the conversion, I added a condition so that when editing a staff notice, the save button is disabled as long as no changes have been made.
This commit is contained in:
Ted Johansson 2023-10-02 17:33:42 +02:00 committed by GitHub
parent f314eaae55
commit fe15218d8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 95 deletions

View File

@ -0,0 +1,30 @@
<DModal
@title={{if
@model.post.notice
(i18n "post.controls.change_post_notice")
(i18n "post.controls.add_post_notice")
}}
@closeModal={{@closeModal}}
class="change-post-notice-modal"
>
<:body>
<form><Textarea @value={{this.notice}} /></form>
</:body>
<:footer>
<DButton
@label={{if this.saving "saving" "save"}}
@action={{fn this.setNotice this.notice}}
@disabled={{this.disabled}}
class="btn-primary"
/>
{{#if @model.post.notice}}
<DButton
@label="post.controls.delete_post_notice"
@action={{this.setNotice}}
@disabled={{this.saving}}
class="btn-danger"
/>
{{/if}}
<DModalCancel @close={{@closeModal}} />
</:footer>
</DModal>

View File

@ -0,0 +1,63 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { cookAsync } from "discourse/lib/text";
import { isEmpty } from "@ember/utils";
export default class ChangePostNoticeModal extends Component {
@tracked post = this.args.model.post;
@tracked notice = this.args.model.post.notice?.raw ?? "";
@tracked saving = false;
resolve = this.args.model.resolve;
reject = this.args.model.reject;
get disabled() {
return (
this.saving ||
isEmpty(this.notice) ||
this.notice === this.post.notice?.raw
);
}
@action
saveNotice() {
this.setNotice(this.notice);
}
@action
deleteNotice() {
this.setNotice();
}
@action
setNotice(notice) {
const { resolve, reject } = this;
this.saving = true;
this.resolve = null;
this.reject = null;
this.post
.updatePostField("notice", notice)
.then(() => {
if (notice) {
return cookAsync(notice, { features: { onebox: false } });
}
})
.then((cooked) =>
this.post.set(
"notice",
cooked
? {
type: "custom",
raw: notice,
cooked: cooked.toString(),
}
: null
)
)
.then(resolve, reject)
.finally(() => this.args.closeModal());
}
}

View File

@ -1,58 +0,0 @@
import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { action } from "@ember/object";
import { cookAsync } from "discourse/lib/text";
import discourseComputed from "discourse-common/utils/decorators";
import { isEmpty } from "@ember/utils";
export default Controller.extend(ModalFunctionality, {
post: null,
resolve: null,
reject: null,
notice: null,
saving: false,
@discourseComputed("saving", "notice")
disabled(saving, notice) {
return saving || isEmpty(notice);
},
onShow() {
this.setProperties({ notice: "", saving: false });
},
onClose() {
if (this.reject) {
this.reject();
}
},
@action
setNotice(notice) {
const { resolve, reject } = this;
this.setProperties({ saving: true, resolve: null, reject: null });
this.model
.updatePostField("notice", notice)
.then(() => {
if (notice) {
return cookAsync(notice, { features: { onebox: false } });
}
})
.then((cooked) =>
this.model.set(
"notice",
cooked
? {
type: "custom",
raw: notice,
cooked: cooked.toString(),
}
: null
)
)
.then(resolve, reject)
.finally(() => this.send("closeModal"));
},
});

View File

@ -11,6 +11,7 @@ import { isEmpty, isPresent } from "@ember/utils";
import { next, schedule } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import BookmarkModal from "discourse/components/modal/bookmark";
import ChangePostNoticeModal from "discourse/components/modal/change-post-notice";
import {
CLOSE_INITIATED_BY_BUTTON,
CLOSE_INITIATED_BY_ESC,
@ -32,7 +33,6 @@ import { escapeExpression, modKeysPressed } from "discourse/lib/utilities";
import { extractLinkMeta } from "discourse/lib/render-topic-featured-link";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
import showModal from "discourse/lib/show-modal";
import { spinnerHTML } from "discourse/helpers/loading-spinner";
import { BookmarkFormData } from "discourse/lib/bookmark";
import DeleteTopicConfirmModal from "discourse/components/modal/delete-topic-confirm";
@ -997,15 +997,8 @@ export default Controller.extend(bufferedProperty("model"), {
this.send("showGrantBadgeModal");
},
changeNotice(post) {
return new Promise(function (resolve, reject) {
const modal = showModal("change-post-notice", { model: post });
modal.setProperties({
resolve,
reject,
notice: post.notice ? post.notice.raw : "",
});
});
async changeNotice(post) {
await this.modal.show(ChangePostNoticeModal, { model: { post } });
},
filterParticipant(user) {

View File

@ -1,27 +0,0 @@
<DModalBody
@title={{if
this.model.notice
"post.controls.change_post_notice"
"post.controls.add_post_notice"
}}
>
<form><Textarea @value={{this.notice}} /></form>
</DModalBody>
<div class="modal-footer">
<DButton
@label={{if this.saving "saving" "save"}}
@action={{fn this.setNotice this.notice}}
@disabled={{this.disabled}}
class="btn-primary"
/>
{{#if this.model.notice}}
<DButton
@label="post.controls.delete_post_notice"
@action={{this.setNotice}}
@disabled={{this.saving}}
class="btn-danger"
/>
{{/if}}
<DModalCancel @close={{route-action "closeModal"}} />
</div>