From e01f75cb32bceeb52bb0a0b10e77bb81d9657591 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Wed, 6 Mar 2024 21:13:38 +0100 Subject: [PATCH] DEV: Convert edit-topic-timer-form to glimmer (#25995) --- .../app/components/edit-topic-timer-form.hbs | 43 ++-- .../app/components/edit-topic-timer-form.js | 226 ++++++++---------- .../tests/acceptance/topic-edit-timer-test.js | 101 ++++---- 3 files changed, 170 insertions(+), 200 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.hbs b/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.hbs index 37efaae1b03..2ed1e55999b 100644 --- a/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.hbs +++ b/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.hbs @@ -1,61 +1,66 @@
+ {{#if this.publishToCategory}}
- +
{{/if}} + {{#if this.showFutureDateInput}} - + {{/if}} + {{#if this.useDuration}}
- +
{{/if}} + {{#if this.willCloseImmediately}}
{{d-icon "exclamation-triangle"}} {{this.willCloseI18n}}
{{/if}} + {{#if this.showTopicTimerInfo}} {{/if}} diff --git a/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.js b/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.js index bfb2dafa926..d9850b336b3 100644 --- a/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.js +++ b/app/assets/javascripts/discourse/app/components/edit-topic-timer-form.js @@ -1,6 +1,7 @@ -import Component from "@ember/component"; +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; import { action } from "@ember/object"; -import { equal, or, readOnly } from "@ember/object/computed"; +import { inject as service } from "@ember/service"; import { isEmpty } from "@ember/utils"; import ItsATrap from "@discourse/itsatrap"; import { @@ -17,73 +18,71 @@ import { TIME_SHORTCUT_TYPES, timeShortcuts, } from "discourse/lib/time-shortcut"; -import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; import { FORMAT } from "select-kit/components/future-date-input-selector"; -export default Component.extend({ - statusType: readOnly("topicTimer.status_type"), - autoOpen: equal("statusType", OPEN_STATUS_TYPE), - autoClose: equal("statusType", CLOSE_STATUS_TYPE), - autoCloseAfterLastPost: equal( - "statusType", - CLOSE_AFTER_LAST_POST_STATUS_TYPE - ), - autoDelete: equal("statusType", DELETE_STATUS_TYPE), - autoBump: equal("statusType", BUMP_TYPE), - publishToCategory: equal("statusType", PUBLISH_TO_CATEGORY_STATUS_TYPE), - autoDeleteReplies: equal("statusType", DELETE_REPLIES_TYPE), - showTimeOnly: or("autoOpen", "autoDelete", "autoBump"), - showFutureDateInput: or("showTimeOnly", "publishToCategory", "autoClose"), - useDuration: or( - "isBasedOnLastPost", - "autoDeleteReplies", - "autoCloseAfterLastPost" - ), - duration: null, - _itsatrap: null, +export default class EditTopicTimerForm extends Component { + @service currentUser; - init() { - this._super(...arguments); + @tracked timerType; + + constructor() { + super(...arguments); KeyboardShortcuts.pause(); - this.set("_itsatrap", new ItsATrap()); + this._itsatrap = new ItsATrap(); + } - this.set("duration", this.initialDuration); - }, - - get initialDuration() { - if (!this.useDuration || !this.topicTimer.duration_minutes) { - return null; - } else if (this.durationType === "days") { - return this.topicTimer.duration_minutes / 60 / 24; - } else { - return this.topicTimer.duration_minutes / 60; - } - }, - - willDestroyElement() { - this._super(...arguments); + willDestroy() { + super.willDestroy(...arguments); this._itsatrap.destroy(); - this.set("_itsatrap", null); KeyboardShortcuts.unpause(); - }, + } - @discourseComputed("autoDeleteReplies") - durationType(autoDeleteReplies) { - return autoDeleteReplies ? "days" : "hours"; - }, + get showTimeOnly() { + return ( + this.statusType === OPEN_STATUS_TYPE || + this.statusType === DELETE_STATUS_TYPE || + this.statusType === BUMP_TYPE + ); + } - @discourseComputed("topic.visible") - excludeCategoryId(visible) { - if (visible) { - return this.get("topic.category_id"); + get showFutureDateInput() { + return ( + this.showTimeOnly || + this.publishToCategory || + this.statusType === CLOSE_STATUS_TYPE + ); + } + + get useDuration() { + return this.autoCloseAfterLastPost || this.autoDeleteReplies; + } + + get autoCloseAfterLastPost() { + return this.statusType === CLOSE_AFTER_LAST_POST_STATUS_TYPE; + } + + get publishToCategory() { + return this.statusType === PUBLISH_TO_CATEGORY_STATUS_TYPE; + } + + get autoDeleteReplies() { + return this.statusType === DELETE_REPLIES_TYPE; + } + + get statusType() { + return this.args.topicTimer.status_type; + } + + get excludeCategoryId() { + if (this.args.topic.visible) { + return this.args.topic.category_id; } - }, + } - @discourseComputed() - timeOptions() { + get timeOptions() { const timezone = this.currentUser.user_option.timezone; const shortcuts = timeShortcuts(timezone); @@ -97,106 +96,85 @@ export default Component.extend({ shortcuts.nextMonth(), shortcuts.sixMonths(), ]; - }, + } - @discourseComputed - hiddenTimeShortcutOptions() { + get hiddenTimeShortcutOptions() { return [ TIME_SHORTCUT_TYPES.NONE, TIME_SHORTCUT_TYPES.LATER_TODAY, TIME_SHORTCUT_TYPES.LATER_THIS_WEEK, ]; - }, + } - isCustom: equal("timerType", "custom"), - isBasedOnLastPost: equal("statusType", "close_after_last_post"), - - @discourseComputed( - "topicTimer.updateTime", - "topicTimer.duration_minutes", - "useDuration" - ) - executeAt(updateTime, duration, useDuration) { - if (useDuration) { - return moment().add(parseFloat(duration), "minutes").format(FORMAT); + get executeAt() { + if (this.useDuration) { + return moment() + .add(parseFloat(this.args.topicTimer.duration_minutes), "minutes") + .format(FORMAT); } else { - return updateTime; + return this.args.topicTimer.updateTime; } - }, + } - @discourseComputed( - "isBasedOnLastPost", - "topicTimer.duration_minutes", - "topic.last_posted_at" - ) - willCloseImmediately(isBasedOnLastPost, duration, lastPostedAt) { - if (isBasedOnLastPost && duration) { - let closeDate = moment(lastPostedAt); - closeDate = closeDate.add(duration, "minutes"); + get willCloseImmediately() { + if (this.autoCloseAfterLastPost && this.args.topicTimer.duration_minutes) { + const closeDate = moment(this.args.topic.last_posted_at).add( + this.args.topicTimer.duration_minutes, + "minutes" + ); return closeDate < moment(); } - }, + } - @discourseComputed("isBasedOnLastPost", "topic.last_posted_at") - willCloseI18n(isBasedOnLastPost, lastPostedAt) { - if (isBasedOnLastPost) { + get willCloseI18n() { + if (this.autoCloseAfterLastPost) { const diff = Math.round( - (new Date() - new Date(lastPostedAt)) / (1000 * 60 * 60) + (new Date() - new Date(this.args.topic.last_posted_at)) / + (1000 * 60 * 60) ); return I18n.t("topic.auto_close_momentarily", { count: diff }); } - }, + } - @discourseComputed("durationType") - durationLabel(durationType) { - return I18n.t(`topic.topic_status_update.num_of_${durationType}`); - }, + get durationLabel() { + return I18n.t( + `topic.topic_status_update.num_of_${ + this.autoDeleteReplies ? "days" : "hours" + }` + ); + } - @discourseComputed( - "statusType", - "isCustom", - "topicTimer.updateTime", - "willCloseImmediately", - "topicTimer.category_id", - "useDuration", - "topicTimer.duration_minutes" - ) - showTopicTimerInfo( - statusType, - isCustom, - updateTime, - willCloseImmediately, - categoryId, - useDuration, - duration - ) { - if (!statusType || willCloseImmediately) { + get showTopicTimerInfo() { + if (!this.statusType || this.willCloseImmediately) { return false; } - if (statusType === PUBLISH_TO_CATEGORY_STATUS_TYPE && isEmpty(categoryId)) { + if ( + this.statusType === PUBLISH_TO_CATEGORY_STATUS_TYPE && + isEmpty(this.args.topicTimer.category_id) + ) { return false; } - if (isCustom && updateTime) { - if (moment(updateTime) < moment()) { + if (this.timerType === "custom" && this.args.topicTimer.updateTime) { + if (moment(this.args.topicTimer.updateTime) < moment()) { return false; } - } else if (useDuration) { - return duration; + } else if (this.useDuration) { + return this.args.topicTimer.duration_minutes; } - return updateTime; - }, + return this.args.topicTimer.updateTime; + } @action onTimeSelected(type, time) { - this.set("timerType", type); - this.onChangeInput(type, time); - }, + this.timerType = type; + this.args.onChangeInput(type, time); + } @action - durationChanged(newDurationMins) { - this.set("topicTimer.duration_minutes", newDurationMins); - }, -}); + changeDuration(newDurationMins) { + this.args.topicTimer.set("duration_minutes", newDurationMins); + } +} diff --git a/app/assets/javascripts/discourse/tests/acceptance/topic-edit-timer-test.js b/app/assets/javascripts/discourse/tests/acceptance/topic-edit-timer-test.js index 6b9e9d018c1..248712938a1 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/topic-edit-timer-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/topic-edit-timer-test.js @@ -3,7 +3,6 @@ import { test } from "qunit"; import topicFixtures from "discourse/tests/fixtures/topic"; import { acceptance, - exists, fakeTime, loggedInUser, query, @@ -54,11 +53,9 @@ acceptance("Topic - Edit timer", function (needs) { await click("#tap_tile_start_of_next_business_week"); - const regex = /will automatically close in/g; - const html = query( - ".edit-topic-timer-modal .topic-timer-info" - ).innerHTML.trim(); - assert.ok(regex.test(html)); + assert + .dom(".edit-topic-timer-modal .topic-timer-info") + .matchesText(/will automatically close in/g); }); test("autoclose", async function (assert) { @@ -70,20 +67,16 @@ acceptance("Topic - Edit timer", function (needs) { await click("#tap_tile_start_of_next_business_week"); - const regex1 = /will automatically close in/g; - const html1 = query( - ".edit-topic-timer-modal .topic-timer-info" - ).innerHTML.trim(); - assert.ok(regex1.test(html1)); + assert + .dom(".edit-topic-timer-modal .topic-timer-info") + .matchesText(/will automatically close in/g); await click("#tap_tile_custom"); await fillIn(".tap-tile-date-input .date-picker", "2100-11-24"); - const regex2 = /will automatically close in/g; - const html2 = query( - ".edit-topic-timer-modal .topic-timer-info" - ).innerHTML.trim(); - assert.ok(regex2.test(html2)); + assert + .dom(".edit-topic-timer-modal .topic-timer-info") + .matchesText(/will automatically close in/g); const timerType = selectKit(".select-kit.timer-type"); await timerType.expand(); @@ -94,9 +87,9 @@ acceptance("Topic - Edit timer", function (needs) { await interval.selectRowByValue("hours"); await fillIn(".relative-time-duration", "2"); - const regex3 = /last post in the topic is already/g; - const html3 = query(".edit-topic-timer-modal .warning").innerHTML.trim(); - assert.ok(regex3.test(html3)); + assert + .dom(".edit-topic-timer-modal .warning") + .matchesText(/last post in the topic is already/g); }); test("close temporarily", async function (assert) { @@ -112,20 +105,16 @@ acceptance("Topic - Edit timer", function (needs) { await click("#tap_tile_start_of_next_business_week"); - const regex1 = /will automatically open in/g; - const html1 = query( - ".edit-topic-timer-modal .topic-timer-info" - ).innerHTML.trim(); - assert.ok(regex1.test(html1)); + assert + .dom(".edit-topic-timer-modal .topic-timer-info") + .matchesText(/will automatically open in/g); await click("#tap_tile_custom"); await fillIn(".tap-tile-date-input .date-picker", "2100-11-24"); - const regex2 = /will automatically open in/g; - const html2 = query( - ".edit-topic-timer-modal .topic-timer-info" - ).innerHTML.trim(); - assert.ok(regex2.test(html2)); + assert + .dom(".edit-topic-timer-modal .topic-timer-info") + .matchesText(/will automatically open in/g); }); test("schedule publish to category - visible for a PM", async function (assert) { @@ -257,10 +246,11 @@ acceptance("Topic - Edit timer", function (needs) { await click(".toggle-admin-menu"); await click(".admin-topic-timer-update button"); - assert.notOk( - exists("#tap_tile_last_custom"), - "it does not show last custom if the custom date and time was not filled before" - ); + assert + .dom("#tap_tile_last_custom") + .doesNotExist( + "it does not show last custom if the custom date and time was not filled before" + ); await click(".modal-close"); await click(".toggle-admin-menu"); @@ -273,13 +263,11 @@ acceptance("Topic - Edit timer", function (needs) { await click(".toggle-admin-menu"); await click(".admin-topic-timer-update button"); - assert.ok( - exists("#tap_tile_last_custom"), - "it show last custom because the custom date and time was valid" - ); - const text = query("#tap_tile_last_custom").innerText.trim(); - const regex = /Nov 24, 10:30 am/g; - assert.ok(regex.test(text)); + assert + .dom("#tap_tile_last_custom") + .exists("it show last custom because the custom date and time was valid"); + + assert.dom("#tap_tile_last_custom").matchesText(/Nov 24, 10:30 am/g); }); test("schedule publish to category - does not show for a public topic", async function (assert) { @@ -291,7 +279,7 @@ acceptance("Topic - Edit timer", function (needs) { await click(".admin-topic-timer-update button"); await timerType.expand(); - assert.notOk( + assert.false( timerType.rowByValue("publish_to_category").exists(), "publish to category is not shown for a public topic" ); @@ -308,7 +296,7 @@ acceptance("Topic - Edit timer", function (needs) { await timerType.expand(); - assert.ok(!timerType.rowByValue("delete").exists()); + assert.false(timerType.rowByValue("delete").exists()); }); test("Category Moderator can auto-delete replies", async function (assert) { @@ -322,7 +310,7 @@ acceptance("Topic - Edit timer", function (needs) { await timerType.expand(); - assert.ok(timerType.rowByValue("delete_replies").exists()); + assert.true(timerType.rowByValue("delete_replies").exists()); }); test("TL4 can't auto-delete replies", async function (assert) { @@ -336,7 +324,7 @@ acceptance("Topic - Edit timer", function (needs) { await timerType.expand(); - assert.ok(!timerType.rowByValue("delete_replies").exists()); + assert.false(timerType.rowByValue("delete_replies").exists()); }); test("Category Moderator can auto-delete", async function (assert) { @@ -350,7 +338,7 @@ acceptance("Topic - Edit timer", function (needs) { await timerType.expand(); - assert.ok(timerType.rowByValue("delete").exists()); + assert.true(timerType.rowByValue("delete").exists()); }); test("auto delete", async function (assert) { @@ -366,11 +354,9 @@ acceptance("Topic - Edit timer", function (needs) { await click("#tap_tile_two_weeks"); - const regex = /will be automatically deleted/g; - const html = query( - ".edit-topic-timer-modal .topic-timer-info" - ).innerHTML.trim(); - assert.ok(regex.test(html)); + assert + .dom(".edit-topic-timer-modal .topic-timer-info") + .matchesText(/will be automatically deleted/g); }); test("Inline delete timer", async function (assert) { @@ -382,11 +368,12 @@ acceptance("Topic - Edit timer", function (needs) { await click("#tap_tile_start_of_next_business_week"); await click(".edit-topic-timer-modal button.btn-primary"); - const removeTimerButton = query(".topic-timer-info .topic-timer-remove"); - assert.strictEqual(removeTimerButton.getAttribute("title"), "remove timer"); + assert + .dom(".topic-timer-info .topic-timer-remove") + .hasAttribute("title", "remove timer"); await click(".topic-timer-info .topic-timer-remove"); - assert.ok(!exists(".topic-timer-info .topic-timer-remove")); + assert.dom(".topic-timer-info .topic-timer-remove").doesNotExist(); }); test("Shows correct time frame options", async function (assert) { @@ -424,7 +411,7 @@ acceptance("Topic - Edit timer", function (needs) { await timerType.expand(); await timerType.selectRowByValue("close_after_last_post"); - assert.notOk(exists(".topic-timer-heading")); + assert.dom(".topic-timer-heading").doesNotExist(); }); test("Close timer removed after manual close", async function (assert) { @@ -439,7 +426,7 @@ acceptance("Topic - Edit timer", function (needs) { await click(".toggle-admin-menu"); await click(".topic-admin-close button"); - assert.notOk(exists(".topic-timer-heading")); + assert.dom(".topic-timer-heading").doesNotExist(); }); test("Open timer removed after manual open", async function (assert) { @@ -457,7 +444,7 @@ acceptance("Topic - Edit timer", function (needs) { await click(".toggle-admin-menu"); await click(".topic-admin-open button"); - assert.notOk(exists(".topic-timer-heading")); + assert.dom(".topic-timer-heading").doesNotExist(); }); test("timer removed after manual toggle close and open", async function (assert) { @@ -475,6 +462,6 @@ acceptance("Topic - Edit timer", function (needs) { await click(".toggle-admin-menu"); await click(".topic-admin-open button"); - assert.notOk(exists(".topic-timer-heading")); + assert.dom(".topic-timer-heading").doesNotExist(); }); });