FEATURE: display count of topics being dismissed in dialog (#23288)
Previous to this change it was unclear if all new would be dismissed or just some of them Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
This commit is contained in:
parent
c9ebc75a1d
commit
997c839626
|
@ -0,0 +1,144 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
import DModal from "discourse/components/d-modal";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import PreferenceCheckbox from "discourse/components/preference-checkbox";
|
||||
import I18n from "I18n";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
|
||||
const REPLIES_SUBSET = "replies";
|
||||
const TOPICS_SUBSET = "topics";
|
||||
|
||||
export default class DismissNew extends Component {
|
||||
<template>
|
||||
<DModal
|
||||
@closeModal={{@closeModal}}
|
||||
@title={{this.modalTitle}}
|
||||
@inline={{@inline}}
|
||||
>
|
||||
<:body>
|
||||
<p>
|
||||
{{#if this.showDismissNewTopics}}
|
||||
<PreferenceCheckbox
|
||||
@labelKey={{this.dismissNewTopicsLabel}}
|
||||
@labelCount={{this.countNewTopics}}
|
||||
@checked={{this.dismissTopics}}
|
||||
@class="dismiss-topics"
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if this.showDismissNewReplies}}
|
||||
<PreferenceCheckbox
|
||||
@labelKey={{this.dismissNewRepliesLabel}}
|
||||
@labelCount={{this.countNewReplies}}
|
||||
@checked={{this.dismissPosts}}
|
||||
@class="dismiss-posts"
|
||||
/>
|
||||
{{/if}}
|
||||
<PreferenceCheckbox
|
||||
@labelKey="topics.bulk.dismiss_new_modal.untrack"
|
||||
@checked={{this.untrack}}
|
||||
@class="untrack"
|
||||
/>
|
||||
</p>
|
||||
</:body>
|
||||
<:footer>
|
||||
<DButton
|
||||
id="dismiss-read-confirm"
|
||||
@action={{this.dismissed}}
|
||||
@icon="check"
|
||||
@label="topics.bulk.dismiss"
|
||||
class="btn-primary"
|
||||
/>
|
||||
</:footer>
|
||||
</DModal>
|
||||
</template>
|
||||
|
||||
@tracked untrack = false;
|
||||
@tracked dismissTopics = true;
|
||||
@tracked dismissPosts = true;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
if (this.args.model.subset === "replies") {
|
||||
this.dismissTopics = false;
|
||||
}
|
||||
if (this.args.model.subset === "topics") {
|
||||
this.dismissPosts = false;
|
||||
}
|
||||
}
|
||||
|
||||
get partialDismiss() {
|
||||
return (this.selectedTopics?.length || 0) !== 0;
|
||||
}
|
||||
|
||||
get dismissNewTopicsLabel() {
|
||||
return (
|
||||
"topics.bulk.dismiss_new_modal.topics" +
|
||||
(this.partialDismiss ? "_with_count" : "")
|
||||
);
|
||||
}
|
||||
|
||||
get dismissNewRepliesLabel() {
|
||||
return (
|
||||
"topics.bulk.dismiss_new_modal.replies" +
|
||||
(this.partialDismiss ? "_with_count" : "")
|
||||
);
|
||||
}
|
||||
|
||||
get showDismissNewTopics() {
|
||||
if (this.partialDismiss) {
|
||||
return this.countNewTopics > 0;
|
||||
}
|
||||
|
||||
return this.subset === TOPICS_SUBSET || !this.subset;
|
||||
}
|
||||
|
||||
get showDismissNewReplies() {
|
||||
if (this.partialDismiss) {
|
||||
return this.countNewReplies > 0;
|
||||
}
|
||||
|
||||
return this.subset === REPLIES_SUBSET || !this.subset;
|
||||
}
|
||||
|
||||
get countNewTopics() {
|
||||
const topics = this.selectedTopics;
|
||||
if (!topics?.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return topics.filter((topic) => !topic.unread_posts).length;
|
||||
}
|
||||
|
||||
get countNewReplies() {
|
||||
const topics = this.selectedTopics;
|
||||
if (!topics?.length) {
|
||||
return 0;
|
||||
}
|
||||
return topics.filter((topic) => topic.unread_posts).length;
|
||||
}
|
||||
|
||||
get subset() {
|
||||
return this.args.model.subset;
|
||||
}
|
||||
|
||||
get selectedTopics() {
|
||||
return this.args.model.selectedTopics;
|
||||
}
|
||||
|
||||
get modalTitle() {
|
||||
return I18n.t("topics.bulk.dismiss_new_modal.title");
|
||||
}
|
||||
|
||||
@action
|
||||
dismissed() {
|
||||
this.args.model.dismissCallback({
|
||||
dismissTopics: this.dismissTopics,
|
||||
dismissPosts: this.dismissPosts,
|
||||
untrack: this.untrack,
|
||||
});
|
||||
|
||||
this.args.closeModal();
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<DModal
|
||||
@closeModal={{@closeModal}}
|
||||
@title={{i18n "topics.bulk.dismiss_new_modal.title"}}
|
||||
>
|
||||
<:body>
|
||||
<p>
|
||||
<PreferenceCheckbox
|
||||
@labelKey="topics.bulk.dismiss_new_modal.topics"
|
||||
@checked={{this.dismissTopics}}
|
||||
@class="dismiss-topics"
|
||||
/>
|
||||
<PreferenceCheckbox
|
||||
@labelKey="topics.bulk.dismiss_new_modal.posts"
|
||||
@checked={{this.dismissPosts}}
|
||||
@class="dismiss-posts"
|
||||
/>
|
||||
<PreferenceCheckbox
|
||||
@labelKey="topics.bulk.dismiss_new_modal.untrack"
|
||||
@checked={{this.untrack}}
|
||||
@class="untrack"
|
||||
/>
|
||||
</p>
|
||||
</:body>
|
||||
<:footer>
|
||||
<DButton
|
||||
id="dismiss-read-confirm"
|
||||
@action={{this.dismissed}}
|
||||
@icon="check"
|
||||
@label="topics.bulk.dismiss"
|
||||
class="btn-primary"
|
||||
/>
|
||||
</:footer>
|
||||
</DModal>
|
|
@ -1,19 +0,0 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export default class DismissNew extends Component {
|
||||
dismissTopics = true;
|
||||
dismissPosts = true;
|
||||
untrack = false;
|
||||
|
||||
@action
|
||||
dismissed() {
|
||||
this.args.model.dismissCallback({
|
||||
dismissTopics: this.dismissTopics,
|
||||
dismissPosts: this.dismissPosts,
|
||||
untrack: this.untrack,
|
||||
});
|
||||
|
||||
this.args.closeModal();
|
||||
}
|
||||
}
|
|
@ -5,9 +5,13 @@ import discourseComputed from "discourse-common/utils/decorators";
|
|||
export default Component.extend({
|
||||
classNames: ["controls"],
|
||||
|
||||
@discourseComputed("labelKey")
|
||||
label(labelKey) {
|
||||
return I18n.t(labelKey);
|
||||
@discourseComputed("labelKey", "labelCount")
|
||||
label(labelKey, labelCount) {
|
||||
if (labelCount) {
|
||||
return I18n.t(labelKey, { count: labelCount });
|
||||
} else {
|
||||
return I18n.t(labelKey);
|
||||
}
|
||||
},
|
||||
|
||||
change() {
|
||||
|
|
|
@ -37,7 +37,7 @@ export default Component.extend({
|
|||
return true;
|
||||
}
|
||||
|
||||
return topicCount > 5;
|
||||
return this.currentUser?.new_new_view_enabled || topicCount > 5;
|
||||
},
|
||||
|
||||
@discourseComputed("selectedTopics.length")
|
||||
|
@ -52,7 +52,7 @@ export default Component.extend({
|
|||
|
||||
@discourseComputed("selectedTopics.length")
|
||||
dismissNewLabel(selectedTopicCount) {
|
||||
if (this.currentUser.new_new_view_enabled) {
|
||||
if (this.currentUser?.new_new_view_enabled) {
|
||||
return I18n.t("topics.bulk.dismiss_button");
|
||||
} else if (selectedTopicCount === 0) {
|
||||
return I18n.t("topics.bulk.dismiss_new");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Mixin from "@ember/object/mixin";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { action } from "@ember/object";
|
||||
import DismissNewModal from "discourse/components/modal/dismiss-new";
|
||||
import DismissNew from "discourse/components/modal/dismiss-new";
|
||||
|
||||
export default Mixin.create({
|
||||
modal: service(),
|
||||
|
@ -13,8 +13,10 @@ export default Mixin.create({
|
|||
return this.callResetNew();
|
||||
}
|
||||
|
||||
this.modal.show(DismissNewModal, {
|
||||
this.modal.show(DismissNew, {
|
||||
model: {
|
||||
selectedTopics: this.selected,
|
||||
subset: this.model.listParams?.subset,
|
||||
dismissCallback: ({ dismissPosts, dismissTopics, untrack }) => {
|
||||
this.callResetNew(dismissPosts, dismissTopics, untrack);
|
||||
},
|
||||
|
|
|
@ -732,22 +732,23 @@ const TopicTrackingState = EmberObject.extend({
|
|||
|
||||
lookupCount({ type, category, tagId, noSubcategories, customFilterFn } = {}) {
|
||||
if (type === "latest") {
|
||||
return (
|
||||
this.lookupCount({
|
||||
type: "new",
|
||||
category,
|
||||
tagId,
|
||||
noSubcategories,
|
||||
customFilterFn,
|
||||
}) +
|
||||
this.lookupCount({
|
||||
let count = this.lookupCount({
|
||||
type: "new",
|
||||
category,
|
||||
tagId,
|
||||
noSubcategories,
|
||||
customFilterFn,
|
||||
});
|
||||
if (!this.currentUser?.new_new_view_enabled) {
|
||||
count += this.lookupCount({
|
||||
type: "unread",
|
||||
category,
|
||||
tagId,
|
||||
noSubcategories,
|
||||
customFilterFn,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
let categoryId = category ? get(category, "id") : null;
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import { click, render } from "@ember/test-helpers";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import I18n from "I18n";
|
||||
|
||||
module("Integration | Component | modal/dismiss-new", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.model = { selectedTopics: [] };
|
||||
});
|
||||
|
||||
test("modal title", async function (assert) {
|
||||
await render(
|
||||
hbs`<Modal::DismissNew @inline={{true}} @model={{this.model}} />`
|
||||
);
|
||||
|
||||
assert
|
||||
.dom("#discourse-modal-title")
|
||||
.hasText(I18n.t("topics.bulk.dismiss_new_modal.title"));
|
||||
});
|
||||
|
||||
test("default state", async function (assert) {
|
||||
await render(
|
||||
hbs`<Modal::DismissNew @inline={{true}} @model={{this.model}} />`
|
||||
);
|
||||
|
||||
assert.dom(".dismiss-topics input").isChecked();
|
||||
assert.dom(".dismiss-posts input").isChecked();
|
||||
assert.dom(".untrack input").isNotChecked();
|
||||
});
|
||||
|
||||
test("one new selected topic", async function (assert) {
|
||||
this.model.selectedTopics.push({
|
||||
id: 1,
|
||||
title: "Topic 1",
|
||||
unread_posts: false,
|
||||
});
|
||||
|
||||
await render(
|
||||
hbs`<Modal::DismissNew @inline={{true}} @model={{this.model}} />`
|
||||
);
|
||||
|
||||
assert.dom(".dismiss-posts").doesNotExist();
|
||||
assert
|
||||
.dom(".dismiss-topics")
|
||||
.hasText(
|
||||
I18n.t("topics.bulk.dismiss_new_modal.topics_with_count", { count: 1 })
|
||||
);
|
||||
});
|
||||
|
||||
test("one new unread in selected topic", async function (assert) {
|
||||
this.model.selectedTopics.push({
|
||||
id: 1,
|
||||
title: "Topic 1",
|
||||
unread_posts: true,
|
||||
});
|
||||
|
||||
await render(
|
||||
hbs`<Modal::DismissNew @inline={{true}} @model={{this.model}} />`
|
||||
);
|
||||
|
||||
assert.dom(".dismiss-topics").doesNotExist();
|
||||
assert
|
||||
.dom(".dismiss-posts")
|
||||
.hasText(
|
||||
I18n.t("topics.bulk.dismiss_new_modal.replies_with_count", { count: 1 })
|
||||
);
|
||||
});
|
||||
|
||||
test("no selected topics with topics subset", async function (assert) {
|
||||
this.model.subset = "topics";
|
||||
|
||||
await render(
|
||||
hbs`<Modal::DismissNew @inline={{true}} @model={{this.model}} />`
|
||||
);
|
||||
|
||||
assert.dom(".dismiss-posts").doesNotExist();
|
||||
assert
|
||||
.dom(".dismiss-topics")
|
||||
.hasText(I18n.t("topics.bulk.dismiss_new_modal.topics"));
|
||||
});
|
||||
|
||||
test("no selected topics with replies subset", async function (assert) {
|
||||
this.model.subset = "replies";
|
||||
|
||||
await render(
|
||||
hbs`<Modal::DismissNew @inline={{true}} @model={{this.model}} />`
|
||||
);
|
||||
|
||||
assert.dom(".dismiss-topics").doesNotExist();
|
||||
assert
|
||||
.dom(".dismiss-posts")
|
||||
.hasText(I18n.t("topics.bulk.dismiss_new_modal.replies"));
|
||||
});
|
||||
|
||||
test("dismissed", async function (assert) {
|
||||
let state;
|
||||
|
||||
this.model.dismissCallback = (newState) => {
|
||||
state = newState;
|
||||
};
|
||||
|
||||
this.noop = () => {};
|
||||
|
||||
await render(
|
||||
hbs`<Modal::DismissNew @closeModal={{this.noop}} @inline={{true}} @model={{this.model}} />`
|
||||
);
|
||||
|
||||
await click(".dismiss-topics [type='checkbox']");
|
||||
await click(".dismiss-posts [type='checkbox']");
|
||||
await click(".untrack [type='checkbox']");
|
||||
await click("#dismiss-read-confirm");
|
||||
|
||||
assert.strictEqual(state.dismissTopics, false);
|
||||
assert.strictEqual(state.dismissPosts, false);
|
||||
assert.strictEqual(state.untrack, true);
|
||||
});
|
||||
});
|
|
@ -2848,7 +2848,14 @@ en:
|
|||
dismiss_new_modal:
|
||||
title: "Dismiss new"
|
||||
topics: "Dismiss new topics"
|
||||
posts: "Dismiss new posts"
|
||||
posts: "Dismiss new replies"
|
||||
topics_with_count:
|
||||
one: "Dismiss %{count} new topic"
|
||||
other: "Dismiss %{count} new topics"
|
||||
replies_with_count:
|
||||
one: "Dismiss %{count} new reply"
|
||||
other: "Dismiss %{count} new replies"
|
||||
replies: "Dismiss new replies"
|
||||
untrack: "Stop tracking these topics so they stop appearing in my new list"
|
||||
dismiss_new_with_selected:
|
||||
one: "Dismiss New (%{count})"
|
||||
|
|
Loading…
Reference in New Issue