DEV: Convert edit-slow-mode modal to component-based API (#22840)

<img width="772" alt="Screenshot 2023-07-28 at 1 41 18 PM" src="https://github.com/discourse/discourse/assets/50783505/9e97c4c8-af29-4e56-80dc-4f0244e2c4db">
This commit is contained in:
Isaac Janzen 2023-08-01 08:17:49 -05:00 committed by GitHub
parent 4191b631bf
commit 99e05b1280
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 257 additions and 258 deletions

View File

@ -0,0 +1,70 @@
<DModal
@title={{i18n "topic.slow_mode_update.title"}}
class="edit-slow-mode-modal"
@closeModal={{@closeModal}}
@flash={{this.flash}}
>
<:body>
<div class="control-group">
<label class="slow-mode-label">
{{i18n "topic.slow_mode_update.description"}}
</label>
</div>
<div class="control-group">
<label class="slow-mode-label">
{{i18n "topic.slow_mode_update.select"}}
</label>
<ComboBox
class="slow-mode-type"
@content={{this.slowModes}}
@value={{this.selectedSlowMode}}
@onChange={{this.setSlowModeDuration}}
/>
</div>
{{#if this.showCustomSelect}}
<div class="control-group">
<label class="slow-mode-label">
{{i18n "topic.slow_mode_update.hours"}}
</label>
<Input @value={{this.hours}} @type="number" class="input-small" />
<label class="slow-mode-label">
{{i18n "topic.slow_mode_update.minutes"}}
</label>
<Input @value={{this.minutes}} @type="number" class="input-small" />
<label class="slow-mode-label">
{{i18n "topic.slow_mode_update.seconds"}}
</label>
<Input @value={{this.seconds}} @type="number" class="input-small" />
</div>
{{/if}}
<div class="control-group">
<FutureDateInput
class="enabled-until"
@label="topic.slow_mode_update.enabled_until"
@labelClasses="slow-mode-label"
@customShortcuts={{this.timeShortcuts}}
@clearable={{true}}
@input={{@model.topic.slow_mode_enabled_until}}
@onChangeInput={{action (mut @model.topic.slow_mode_enabled_until)}}
/>
</div>
</:body>
<:footer>
<DButton
class="btn-primary"
@disabled={{this.submitDisabled}}
@icon="hourglass-start"
@label={{this.saveButtonLabel}}
@action={{this.enableSlowMode}}
/>
{{#if @model.topic.slow_mode_seconds}}
<DButton
class="btn-danger"
@action={{this.disableSlowMode}}
@disabled={{this.submitDisabled}}
@label="topic.slow_mode_update.remove"
/>
{{/if}}
</:footer>
</DModal>

View File

@ -0,0 +1,183 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { fromSeconds, toSeconds } from "discourse/helpers/slow-mode";
import I18n from "I18n";
import { timeShortcuts } from "discourse/lib/time-shortcut";
import Topic from "discourse/models/topic";
import { inject as service } from "@ember/service";
const SLOW_MODE_OPTIONS = [
{
id: "600",
name: I18n.t("topic.slow_mode_update.durations.10_minutes"),
},
{
id: "900",
name: I18n.t("topic.slow_mode_update.durations.15_minutes"),
},
{
id: "1800",
name: I18n.t("topic.slow_mode_update.durations.30_minutes"),
},
{
id: "2700",
name: I18n.t("topic.slow_mode_update.durations.45_minutes"),
},
{
id: "3600",
name: I18n.t("topic.slow_mode_update.durations.1_hour"),
},
{
id: "7200",
name: I18n.t("topic.slow_mode_update.durations.2_hours"),
},
{
id: "14400",
name: I18n.t("topic.slow_mode_update.durations.4_hours"),
},
{
id: "28800",
name: I18n.t("topic.slow_mode_update.durations.8_hours"),
},
{
id: "43200",
name: I18n.t("topic.slow_mode_update.durations.12_hours"),
},
{
id: "86400",
name: I18n.t("topic.slow_mode_update.durations.24_hours"),
},
{
id: "custom",
name: I18n.t("topic.slow_mode_update.durations.custom"),
},
];
export default class EditSlowMode extends Component {
@service currentUser;
@tracked selectedSlowMode;
@tracked hours;
@tracked minutes;
@tracked seconds;
@tracked saveDisabled = false;
@tracked flash;
constructor() {
super(...arguments);
const currentDuration = parseInt(
this.args.model.topic.slow_mode_seconds,
10
);
if (currentDuration) {
const selectedDuration = this.slowModes.find(
(mode) => mode.id === currentDuration.toString()
);
if (selectedDuration) {
this.selectedSlowMode = currentDuration.toString();
} else {
this.selectedSlowMode = "custom";
}
this._setFromSeconds(currentDuration);
}
}
get slowModes() {
return SLOW_MODE_OPTIONS;
}
get saveButtonLabel() {
return this.args.model.topic.slow_mode_seconds &&
this.args.model.topic.slow_mode_seconds !== 0
? "topic.slow_mode_update.update"
: "topic.slow_mode_update.enable";
}
get timeShortcuts() {
const timezone = this.currentUser.user_option.timezone;
const shortcuts = timeShortcuts(timezone);
const nextWeek = shortcuts.monday();
nextWeek.label = "time_shortcut.next_week";
return [
shortcuts.laterToday(),
shortcuts.tomorrow(),
shortcuts.twoDays(),
nextWeek,
shortcuts.twoWeeks(),
shortcuts.nextMonth(),
shortcuts.twoMonths(),
];
}
get showCustomSelect() {
return this.selectedSlowMode === "custom";
}
get durationIsSet() {
return this.hours || this.minutes || this.seconds;
}
@action
async enableSlowMode() {
this.saveDisabled = true;
const seconds = toSeconds(
this._parseValue(this.hours),
this._parseValue(this.minutes),
this._parseValue(this.seconds)
);
try {
await Topic.setSlowMode(
this.args.model.topic.id,
seconds,
this.args.model.topic.slow_mode_enabled_until
);
this.args.model.topic.set("slow_mode_seconds", seconds);
this.args.closeModal();
} catch {
this.flash = I18n.t("generic_error");
} finally {
this.saveDisabled = false;
}
}
@action
async disableSlowMode() {
this.saveDisabled = true;
try {
await Topic.setSlowMode(this.args.model.topic.id, 0);
this.args.model.topic.set("slow_mode_seconds", 0);
this.args.closeModal();
} catch (e) {
this.flash = e;
} finally {
this.saveDisabled = false;
}
}
@action
setSlowModeDuration(duration) {
if (duration !== "custom") {
let seconds = parseInt(duration, 10);
this._setFromSeconds(seconds);
}
this.selectedSlowMode = duration;
}
_setFromSeconds(seconds) {
const { hours, minutes, seconds: componentSeconds } = fromSeconds(seconds);
this.hours = hours;
this.minutes = minutes;
this.seconds = componentSeconds;
}
_parseValue(value) {
return parseInt(value, 10) || 0;
}
}

View File

@ -1,183 +0,0 @@
import { fromSeconds, toSeconds } from "discourse/helpers/slow-mode";
import Controller from "@ember/controller";
import I18n from "I18n";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import Topic from "discourse/models/topic";
import { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import { equal, or } from "@ember/object/computed";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { timeShortcuts } from "discourse/lib/time-shortcut";
export default Controller.extend(ModalFunctionality, {
selectedSlowMode: null,
hours: null,
minutes: null,
seconds: null,
saveDisabled: false,
showCustomSelect: equal("selectedSlowMode", "custom"),
durationIsSet: or("hours", "minutes", "seconds"),
init() {
this._super(...arguments);
this.set("slowModes", [
{
id: "600",
name: I18n.t("topic.slow_mode_update.durations.10_minutes"),
},
{
id: "900",
name: I18n.t("topic.slow_mode_update.durations.15_minutes"),
},
{
id: "1800",
name: I18n.t("topic.slow_mode_update.durations.30_minutes"),
},
{
id: "2700",
name: I18n.t("topic.slow_mode_update.durations.45_minutes"),
},
{
id: "3600",
name: I18n.t("topic.slow_mode_update.durations.1_hour"),
},
{
id: "7200",
name: I18n.t("topic.slow_mode_update.durations.2_hours"),
},
{
id: "14400",
name: I18n.t("topic.slow_mode_update.durations.4_hours"),
},
{
id: "28800",
name: I18n.t("topic.slow_mode_update.durations.8_hours"),
},
{
id: "43200",
name: I18n.t("topic.slow_mode_update.durations.12_hours"),
},
{
id: "86400",
name: I18n.t("topic.slow_mode_update.durations.24_hours"),
},
{
id: "custom",
name: I18n.t("topic.slow_mode_update.durations.custom"),
},
]);
},
onShow() {
const currentDuration = parseInt(this.model.slow_mode_seconds, 10);
if (currentDuration) {
const selectedDuration = this.slowModes.find((mode) => {
return mode.id === currentDuration.toString();
});
if (selectedDuration) {
this.set("selectedSlowMode", currentDuration.toString());
} else {
this.set("selectedSlowMode", "custom");
}
this._setFromSeconds(currentDuration);
}
},
@discourseComputed(
"saveDisabled",
"durationIsSet",
"model.slow_mode_enabled_until"
)
submitDisabled(saveDisabled, durationIsSet, enabledUntil) {
return saveDisabled || !durationIsSet || !enabledUntil;
},
@discourseComputed("model.slow_mode_seconds")
slowModeEnabled(slowModeSeconds) {
return slowModeSeconds && slowModeSeconds !== 0;
},
@discourseComputed("slowModeEnabled")
saveButtonLabel(slowModeEnabled) {
return slowModeEnabled
? "topic.slow_mode_update.update"
: "topic.slow_mode_update.enable";
},
@discourseComputed
timeShortcuts() {
const timezone = this.currentUser.user_option.timezone;
const shortcuts = timeShortcuts(timezone);
const nextWeek = shortcuts.monday();
nextWeek.label = "time_shortcut.next_week";
return [
shortcuts.laterToday(),
shortcuts.tomorrow(),
shortcuts.twoDays(),
nextWeek,
shortcuts.twoWeeks(),
shortcuts.nextMonth(),
shortcuts.twoMonths(),
];
},
_setFromSeconds(seconds) {
this.setProperties(fromSeconds(seconds));
},
_parseValue(value) {
return parseInt(value, 10) || 0;
},
@action
setSlowModeDuration(duration) {
if (duration !== "custom") {
let seconds = parseInt(duration, 10);
this._setFromSeconds(seconds);
}
this.set("selectedSlowMode", duration);
},
@action
enableSlowMode() {
this.set("saveDisabled", true);
const seconds = toSeconds(
this._parseValue(this.hours),
this._parseValue(this.minutes),
this._parseValue(this.seconds)
);
Topic.setSlowMode(
this.model.id,
seconds,
this.model.slow_mode_enabled_until
)
.catch(popupAjaxError)
.then(() => {
this.set("model.slow_mode_seconds", seconds);
this.send("closeModal");
})
.finally(() => this.set("saveDisabled", false));
},
@action
disableSlowMode() {
this.set("saveDisabled", true);
Topic.setSlowMode(this.model.id, 0)
.catch(popupAjaxError)
.then(() => {
this.set("model.slow_mode_seconds", 0);
this.send("closeModal");
})
.finally(() => this.set("saveDisabled", false));
},
});

View File

@ -12,6 +12,7 @@ import TopicFlag from "discourse/lib/flag-targets/topic-flag";
import PostFlag from "discourse/lib/flag-targets/post-flag";
import HistoryModal from "discourse/components/modal/history";
import PublishPageModal from "discourse/components/modal/publish-page";
import EditSlowModeModal from "discourse/components/modal/edit-slow-mode";
const SCROLL_DELAY = 500;
@ -131,9 +132,9 @@ const TopicRoute = DiscourseRoute.extend({
@action
showTopicSlowModeUpdate() {
const model = this.modelFor("topic");
showModal("edit-slow-mode", { model });
this.modal.show(EditSlowModeModal, {
model: { topic: this.modelFor("topic") },
});
},
@action

View File

@ -25,7 +25,6 @@ const KNOWN_LEGACY_MODALS = [
"create-invite-bulk",
"create-invite",
"download-calendar",
"edit-slow-mode",
"edit-topic-timer",
"edit-user-directory-columns",
"explain-reviewable",

View File

@ -1,71 +0,0 @@
<DModalBody @title="topic.slow_mode_update.title" @autoFocus={{false}}>
<div class="control-group">
<label class="slow-mode-label">{{i18n
"topic.slow_mode_update.description"
}}</label>
</div>
<div class="control-group">
<label class="slow-mode-label">{{i18n
"topic.slow_mode_update.select"
}}</label>
<ComboBox
@class="slow-mode-type"
@content={{this.slowModes}}
@value={{this.selectedSlowMode}}
@onChange={{action "setSlowModeDuration"}}
/>
</div>
{{#if this.showCustomSelect}}
<div class="control-group">
<label class="slow-mode-label">{{i18n
"topic.slow_mode_update.hours"
}}</label>
<Input @value={{this.hours}} @type="number" class="input-small" />
<label class="slow-mode-label">{{i18n
"topic.slow_mode_update.minutes"
}}</label>
<Input @value={{this.minutes}} @type="number" class="input-small" />
<label class="slow-mode-label">{{i18n
"topic.slow_mode_update.seconds"
}}</label>
<Input @value={{this.seconds}} @type="number" class="input-small" />
</div>
{{/if}}
<div class="control-group">
<FutureDateInput
@class="enabled-until"
@label="topic.slow_mode_update.enabled_until"
@labelClasses="slow-mode-label"
@customShortcuts={{this.timeShortcuts}}
@clearable={{true}}
@input={{this.model.slow_mode_enabled_until}}
@onChangeInput={{action (mut this.model.slow_mode_enabled_until)}}
/>
</div>
</DModalBody>
<div class="modal-footer">
<DButton
@class="btn-primary"
@disabled={{this.submitDisabled}}
@icon="hourglass-start"
@label={{this.saveButtonLabel}}
@action={{action "enableSlowMode"}}
/>
<ConditionalLoadingSpinner @size="small" @condition={{this.loading}} />
{{#if this.model.slow_mode_seconds}}
<DButton
@class="btn-danger"
@action={{action "disableSlowMode"}}
@disabled={{this.submitDisabled}}
@label="topic.slow_mode_update.remove"
/>
{{/if}}
</div>