DEV: Convert user-status modal to a glimmer component (#23798)

This commit is contained in:
Jarek Radosz 2023-10-05 21:22:28 +02:00 committed by GitHub
parent 4db41ed28a
commit 8a6aaf9446
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 66 deletions

View File

@ -1,20 +1,22 @@
<DModal
@title={{i18n "user_status.set_custom_status"}}
@closeModal={{@closeModal}}
class="user-status"
@title={{i18n "user_status.set_custom_status"}}
>
<:body>
<div class="control-group">
<UserStatusPicker @status={{this.status}} />
</div>
{{#unless this.hidePauseNotifications}}
{{#unless @model.hidePauseNotifications}}
<div class="control-group pause-notifications">
<label class="checkbox-label">
<Input @type="checkbox" @checked={{this.pauseNotifications}} />
<Input @type="checkbox" @checked={{@model.pauseNotifications}} />
{{i18n "user_status.pause_notifications"}}
</label>
</div>
{{/unless}}
<div class="control-group control-group-remove-status">
<label class="control-label">
{{i18n "user_status.remove_status"}}
@ -30,14 +32,17 @@
/>
</div>
</:body>
<:footer>
<DButton
@label="user_status.save"
@disabled={{not this.statusIsSet}}
@disabled={{this.saveDisabled}}
@action={{this.saveAndClose}}
class="btn-primary"
/>
<DModalCancel @close={{@closeModal}} />
{{#if this.showDeleteButton}}
<DButton
@icon="trash-alt"

View File

@ -1,84 +1,55 @@
import Component from "@glimmer/component";
import { inject as service } from "@ember/service";
import { TrackedObject } from "@ember-compat/tracked-built-ins";
import { action } from "@ember/object";
import { popupAjaxError } from "discourse/lib/ajax-error";
import discourseComputed from "discourse-common/utils/decorators";
import ItsATrap from "@discourse/itsatrap";
import {
TIME_SHORTCUT_TYPES,
timeShortcuts,
} from "discourse/lib/time-shortcut";
import Component from "@ember/component";
export default class ModalUserStatus extends Component {
showDeleteButton = false;
prefilledDateTime = null;
timeShortcuts = null;
_itsatrap = null;
export default class UserStatusModal extends Component {
@service currentUser;
@service dialog;
init() {
super.init(...arguments);
const currentStatus = { ...this.model.status };
this.setProperties({
status: currentStatus,
hidePauseNotifications: this.model.hidePauseNotifications,
pauseNotifications: this.model.pauseNotifications,
showDeleteButton: !!this.model.status,
timeShortcuts: this._buildTimeShortcuts(),
prefilledDateTime: currentStatus?.ends_at,
});
this.set("_itsatrap", new ItsATrap());
}
status = new TrackedObject({ ...this.args.model.status });
timeShortcuts = this.#buildTimeShortcuts();
_itsatrap = new ItsATrap();
willDestroy() {
super.willDestroy(...arguments);
this._itsatrap.destroy();
this.set("_itsatrap", null);
this.set("timeShortcuts", null);
}
@discourseComputed("status.emoji", "status.description")
statusIsSet(emoji, description) {
return !!emoji && !!description;
get showDeleteButton() {
return !!this.args.model.status;
}
@discourseComputed
customTimeShortcutLabels() {
const labels = {};
labels[TIME_SHORTCUT_TYPES.NONE] = "time_shortcut.never";
return labels;
get prefilledDateTime() {
return this.status?.ends_at;
}
@discourseComputed
hiddenTimeShortcutOptions() {
get saveDisabled() {
return !this.status?.emoji || !this.status?.description;
}
get customTimeShortcutLabels() {
return {
[TIME_SHORTCUT_TYPES.NONE]: "time_shortcut.never",
};
}
get hiddenTimeShortcutOptions() {
return [TIME_SHORTCUT_TYPES.LAST_CUSTOM];
}
@action
delete() {
Promise.resolve(this.model.deleteAction())
.then(() => this.closeModal())
.catch((e) => this._handleError(e));
#buildTimeShortcuts() {
const shortcuts = timeShortcuts(this.currentUser.user_option.timezone);
return [shortcuts.oneHour(), shortcuts.twoHours(), shortcuts.tomorrow()];
}
@action
onTimeSelected(_, time) {
this.set("status.endsAt", time);
}
@action
saveAndClose() {
const newStatus = {
description: this.status.description,
emoji: this.status.emoji,
ends_at: this.status.endsAt?.toISOString(),
};
Promise.resolve(this.model.saveAction(newStatus, this.pauseNotifications))
.then(() => this.closeModal())
.catch((e) => this._handleError(e));
}
_handleError(e) {
#handleError(e) {
if (typeof e === "string") {
this.dialog.alert(e);
} else {
@ -86,9 +57,37 @@ export default class ModalUserStatus extends Component {
}
}
_buildTimeShortcuts() {
const timezone = this.currentUser.user_option.timezone;
const shortcuts = timeShortcuts(timezone);
return [shortcuts.oneHour(), shortcuts.twoHours(), shortcuts.tomorrow()];
@action
onTimeSelected(_, time) {
this.status.endsAt = time;
}
@action
async delete() {
try {
await this.args.model.deleteAction();
this.args.closeModal();
} catch (e) {
this.#handleError(e);
}
}
@action
async saveAndClose() {
const newStatus = {
description: this.status.description,
emoji: this.status.emoji,
ends_at: this.status.endsAt?.toISOString(),
};
try {
await this.args.model.saveAction(
newStatus,
this.args.model.pauseNotifications
);
this.args.closeModal();
} catch (e) {
this.#handleError(e);
}
}
}