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 <DModal
@title={{i18n "user_status.set_custom_status"}}
@closeModal={{@closeModal}} @closeModal={{@closeModal}}
class="user-status" class="user-status"
@title={{i18n "user_status.set_custom_status"}}
> >
<:body> <:body>
<div class="control-group"> <div class="control-group">
<UserStatusPicker @status={{this.status}} /> <UserStatusPicker @status={{this.status}} />
</div> </div>
{{#unless this.hidePauseNotifications}}
{{#unless @model.hidePauseNotifications}}
<div class="control-group pause-notifications"> <div class="control-group pause-notifications">
<label class="checkbox-label"> <label class="checkbox-label">
<Input @type="checkbox" @checked={{this.pauseNotifications}} /> <Input @type="checkbox" @checked={{@model.pauseNotifications}} />
{{i18n "user_status.pause_notifications"}} {{i18n "user_status.pause_notifications"}}
</label> </label>
</div> </div>
{{/unless}} {{/unless}}
<div class="control-group control-group-remove-status"> <div class="control-group control-group-remove-status">
<label class="control-label"> <label class="control-label">
{{i18n "user_status.remove_status"}} {{i18n "user_status.remove_status"}}
@ -30,14 +32,17 @@
/> />
</div> </div>
</:body> </:body>
<:footer> <:footer>
<DButton <DButton
@label="user_status.save" @label="user_status.save"
@disabled={{not this.statusIsSet}} @disabled={{this.saveDisabled}}
@action={{this.saveAndClose}} @action={{this.saveAndClose}}
class="btn-primary" class="btn-primary"
/> />
<DModalCancel @close={{@closeModal}} /> <DModalCancel @close={{@closeModal}} />
{{#if this.showDeleteButton}} {{#if this.showDeleteButton}}
<DButton <DButton
@icon="trash-alt" @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 { action } from "@ember/object";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import discourseComputed from "discourse-common/utils/decorators";
import ItsATrap from "@discourse/itsatrap"; import ItsATrap from "@discourse/itsatrap";
import { import {
TIME_SHORTCUT_TYPES, TIME_SHORTCUT_TYPES,
timeShortcuts, timeShortcuts,
} from "discourse/lib/time-shortcut"; } from "discourse/lib/time-shortcut";
import Component from "@ember/component";
export default class ModalUserStatus extends Component { export default class UserStatusModal extends Component {
showDeleteButton = false; @service currentUser;
prefilledDateTime = null; @service dialog;
timeShortcuts = null;
_itsatrap = null;
init() { status = new TrackedObject({ ...this.args.model.status });
super.init(...arguments); timeShortcuts = this.#buildTimeShortcuts();
_itsatrap = new ItsATrap();
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());
}
willDestroy() { willDestroy() {
super.willDestroy(...arguments);
this._itsatrap.destroy(); this._itsatrap.destroy();
this.set("_itsatrap", null);
this.set("timeShortcuts", null);
} }
@discourseComputed("status.emoji", "status.description") get showDeleteButton() {
statusIsSet(emoji, description) { return !!this.args.model.status;
return !!emoji && !!description;
} }
@discourseComputed get prefilledDateTime() {
customTimeShortcutLabels() { return this.status?.ends_at;
const labels = {};
labels[TIME_SHORTCUT_TYPES.NONE] = "time_shortcut.never";
return labels;
} }
@discourseComputed get saveDisabled() {
hiddenTimeShortcutOptions() { 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]; return [TIME_SHORTCUT_TYPES.LAST_CUSTOM];
} }
@action #buildTimeShortcuts() {
delete() { const shortcuts = timeShortcuts(this.currentUser.user_option.timezone);
Promise.resolve(this.model.deleteAction()) return [shortcuts.oneHour(), shortcuts.twoHours(), shortcuts.tomorrow()];
.then(() => this.closeModal())
.catch((e) => this._handleError(e));
} }
@action #handleError(e) {
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) {
if (typeof e === "string") { if (typeof e === "string") {
this.dialog.alert(e); this.dialog.alert(e);
} else { } else {
@ -86,9 +57,37 @@ export default class ModalUserStatus extends Component {
} }
} }
_buildTimeShortcuts() { @action
const timezone = this.currentUser.user_option.timezone; onTimeSelected(_, time) {
const shortcuts = timeShortcuts(timezone); this.status.endsAt = time;
return [shortcuts.oneHour(), shortcuts.twoHours(), shortcuts.tomorrow()]; }
@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);
}
} }
} }