DEV: refactor topic map to glimmer component (#26119)

* DEV: add toggle to switch to glimmer TopicMap and rename imported hbs-compiler

* DEV: refactor topic-map tests to use assert.dom

* DEV: add topic-map glimmer component

* DEV: remove topic-map widget and switch summary-box to use explicitly passed-in actions

---------

Co-authored-by: David Taylor <david@taylorhq.com>
This commit is contained in:
Kelv 2024-03-13 09:26:34 +08:00 committed by GitHub
parent 3a4f4abdc9
commit 0353d9fb0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 111 additions and 157 deletions

View File

@ -6,7 +6,7 @@
{{#if @postAttrs.summarizable}}
{{#if this.summary.showSummaryBox}}
<DButton
@action={{this.collapseSummary}}
@action={{@collapseSummary}}
@title="summary.buttons.hide"
@label="summary.buttons.hide"
@icon="chevron-up"
@ -14,7 +14,7 @@
/>
{{else}}
<DButton
@action={{this.generateSummary}}
@action={{@showSummary}}
@translatedLabel={{this.generateSummaryTitle}}
@translatedTitle={{this.generateSummaryTitle}}
@icon={{this.generateSummaryIcon}}
@ -26,7 +26,11 @@
{{#if @postAttrs.hasTopRepliesSummary}}
<DButton
@action={{this.toggleTopRepliesFilter}}
@action={{if
@postAttrs.topicSummaryEnabled
@cancelFilter
@showTopReplies
}}
@translatedTitle={{this.topRepliesTitle}}
@translatedLabel={{this.topRepliesLabel}}
@icon={{this.topRepliesIcon}}

View File

@ -1,5 +1,4 @@
import Component from "@glimmer/component";
import { action } from "@ember/object";
import { service } from "@ember/service";
import I18n from "discourse-i18n";
@ -90,23 +89,4 @@ export default class SummaryBox extends Component {
return "layer-group";
}
@action
toggleTopRepliesFilter() {
const filterFunction = this.topRepliesSummaryEnabled
? "cancelFilter"
: "showTopReplies";
this.args.actionDispatchFunc(filterFunction);
}
@action
collapseSummary() {
this.args.actionDispatchFunc("collapseSummary");
}
@action
generateSummary() {
this.args.actionDispatchFunc("showSummary");
}
}

View File

@ -0,0 +1,54 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import SummaryBox from "discourse/components/summary-box";
import PrivateMessageMap from "discourse/components/topic-map/private-message-map";
import TopicMapExpanded from "discourse/components/topic-map/topic-map-expanded";
import TopicMapSummary from "discourse/components/topic-map/topic-map-summary";
import concatClass from "discourse/helpers/concat-class";
import or from "truth-helpers/helpers/or";
export default class TopicMap extends Component {
@tracked collapsed = !this.args.postAttrs.hasTopRepliesSummary;
@action
toggleMap() {
this.collapsed = !this.collapsed;
}
<template>
<section class={{concatClass "map" (if this.collapsed "map-collapsed")}}>
<TopicMapSummary
@postAttrs={{@postAttrs}}
@toggleMap={{this.toggleMap}}
@collapsed={{this.collapsed}}
/>
</section>
{{#unless this.collapsed}}
<section class="topic-map-expanded">
<TopicMapExpanded @postAttrs={{@postAttrs}} />
</section>
{{/unless}}
{{#if (or @postAttrs.hasTopRepliesSummary @postAttrs.summarizable)}}
<section class="information toggle-summary">
<SummaryBox
@postAttrs={{@postAttrs}}
@cancelFilter={{@cancelFilter}}
@showTopReplies={{@showTopReplies}}
@collapseSummary={{@collapseSummary}}
@showSummary={{@showSummary}}
/>
</section>
{{/if}}
{{#if @postAttrs.showPMMap}}
<section class="information private-message-map">
<PrivateMessageMap
@postAttrs={{@postAttrs}}
@showInvite={{@showInvite}}
@removeAllowedGroup={{@removeAllowedGroup}}
@removeAllowedUser={{@removeAllowedUser}}
/>
</section>
{{/if}}
</template>
}

View File

@ -1,4 +1,5 @@
import { getOwner } from "@ember/application";
import { hbs } from "ember-cli-htmlbars";
import { Promise } from "rsvp";
import { h } from "virtual-dom";
import ShareTopicModal from "discourse/components/modal/share-topic";
@ -15,10 +16,11 @@ import { transformBasicPost } from "discourse/lib/transform-post";
import DiscourseURL from "discourse/lib/url";
import { clipboardCopy, formatUsername } from "discourse/lib/utilities";
import DecoratorHelper from "discourse/widgets/decorator-helper";
import hbs from "discourse/widgets/hbs-compiler";
import widgetHbs from "discourse/widgets/hbs-compiler";
import PostCooked from "discourse/widgets/post-cooked";
import { postTransformCallbacks } from "discourse/widgets/post-stream";
import RawHtml from "discourse/widgets/raw-html";
import RenderGlimmer from "discourse/widgets/render-glimmer";
import { applyDecorators, createWidget } from "discourse/widgets/widget";
import { isTesting } from "discourse-common/config/environment";
import { avatarUrl, translateSize } from "discourse-common/lib/avatar-utils";
@ -263,7 +265,7 @@ createWidget("post-avatar", {
createWidget("post-locked-indicator", {
tagName: "div.post-info.post-locked",
template: hbs`{{d-icon "lock"}}`,
template: widgetHbs`{{d-icon "lock"}}`,
title: () => I18n.t("post.locked"),
});
@ -741,11 +743,40 @@ createWidget("post-body", {
result.push(this.attach("actions-summary", attrs));
result.push(this.attach("post-links", attrs));
if (attrs.showTopicMap) {
result.push(this.attach("topic-map", attrs));
result.push(this.buildTopicMap(attrs));
}
return result;
},
buildTopicMap(attrs) {
return new RenderGlimmer(
this,
"div.topic-map",
hbs`<TopicMap
@postAttrs={{@data.postAttrs}}
@cancelFilter={{@data.cancelFilter}}
@showTopReplies={{@data.showTopReplies}}
@collapseSummary={{@data.collapseSummary}}
@showSummary={{@data.showSummary}}
@showInvite={{@data.showInvite}}
@removeAllowedGroup={{@data.removeAllowedGroup}}
@removeAllowedUser={{@data.removeAllowedUser}}
/>`,
{
postAttrs: attrs,
cancelFilter: () => this.sendWidgetAction("cancelFilter"),
showTopReplies: () => this.sendWidgetAction("showTopReplies"),
collapseSummary: () => this.sendWidgetAction("collapseSummary"),
showSummary: () => this.sendWidgetAction("showSummary"),
showInvite: () => this.sendWidgetAction("showInvite"),
removeAllowedGroup: (group) =>
this.sendWidgetAction("removeAllowedGroup", group),
removeAllowedUser: (user) =>
this.sendWidgetAction("removeAllowedUser", user),
}
);
},
});
createWidget("post-article", {

View File

@ -1,107 +0,0 @@
import { hbs } from "ember-cli-htmlbars";
import RenderGlimmer from "discourse/widgets/render-glimmer";
import { createWidget } from "discourse/widgets/widget";
export default createWidget("topic-map", {
tagName: "div.topic-map",
buildKey: (attrs) => `topic-map-${attrs.id}`,
defaultState(attrs) {
return { collapsed: !attrs.hasTopRepliesSummary };
},
html(attrs, state) {
const contents = [this.buildTopicMapSummary(attrs, state)];
if (!state.collapsed) {
contents.push(this.buildTopicMapExpanded(attrs));
}
if (attrs.hasTopRepliesSummary || attrs.summarizable) {
contents.push(this.buildSummaryBox(attrs));
}
if (attrs.showPMMap) {
contents.push(this.buildPrivateMessageMap(attrs));
}
return contents;
},
toggleMap() {
this.state.collapsed = !this.state.collapsed;
this.scheduleRerender();
},
buildTopicMapSummary(attrs, state) {
const { collapsed } = state;
const wrapperClass = collapsed
? "section.map.map-collapsed"
: "section.map";
return new RenderGlimmer(
this,
wrapperClass,
hbs`<TopicMap::TopicMapSummary
@postAttrs={{@data.postAttrs}}
@toggleMap={{@data.toggleMap}}
@collapsed={{@data.collapsed}}
/>`,
{
toggleMap: this.toggleMap.bind(this),
postAttrs: attrs,
collapsed,
}
);
},
buildTopicMapExpanded(attrs) {
return new RenderGlimmer(
this,
"section.topic-map-expanded",
hbs`<TopicMap::TopicMapExpanded
@postAttrs={{@data.postAttrs}}
/>`,
{
postAttrs: attrs,
}
);
},
buildSummaryBox(attrs) {
return new RenderGlimmer(
this,
"section.information.toggle-summary",
hbs`<SummaryBox
@postAttrs={{@data.postAttrs}}
@actionDispatchFunc={{@data.actionDispatchFunc}}
/>`,
{
postAttrs: attrs,
actionDispatchFunc: (actionName) => {
this.sendWidgetAction(actionName);
},
}
);
},
buildPrivateMessageMap(attrs) {
return new RenderGlimmer(
this,
"section.information.private-message-map",
hbs`<TopicMap::PrivateMessageMap
@postAttrs={{@data.postAttrs}}
@showInvite={{@data.showInvite}}
@removeAllowedGroup={{@data.removeAllowedGroup}}
@removeAllowedUser={{@data.removeAllowedUser}}
/>`,
{
postAttrs: attrs,
showInvite: () => this.sendWidgetAction("showInvite"),
removeAllowedGroup: (group) =>
this.sendWidgetAction("removeAllowedGroup", group),
removeAllowedUser: (user) =>
this.sendWidgetAction("removeAllowedUser", user),
}
);
},
});

View File

@ -3,9 +3,7 @@ import { test } from "qunit";
import topicFixtures from "discourse/tests/fixtures/topic";
import {
acceptance,
exists,
publishToMessageBus,
query,
updateCurrentUser,
} from "discourse/tests/helpers/qunit-helpers";
import { cloneJSON } from "discourse-common/lib/object";
@ -43,11 +41,9 @@ acceptance("Topic - Summary", function (needs) {
await click(".topic-strategy-summarization");
assert.strictEqual(
query(".summary-box .generated-summary p").innerText,
partialSummary,
"Updates the summary with a partial result"
);
assert
.dom(".summary-box .generated-summary p")
.hasText(partialSummary, "Updates the summary with a partial result");
const finalSummary = "This is a completed summary";
await publishToMessageBus("/summaries/topic/1", {
@ -62,13 +58,11 @@ acceptance("Topic - Summary", function (needs) {
},
});
assert.strictEqual(
query(".summary-box .generated-summary p").innerText,
finalSummary,
"Updates the summary with a partial result"
);
assert
.dom(".summary-box .generated-summary p")
.hasText(finalSummary, "Updates the summary with a final result");
assert.ok(exists(".summary-box .summarized-on"), "summary metadata exists");
assert.dom(".summary-box .summarized-on").exists("summary metadata exists");
});
});
@ -103,12 +97,10 @@ acceptance("Topic - Summary - Anon", function (needs) {
await click(".topic-strategy-summarization");
assert.strictEqual(
query(".summary-box .generated-summary p").innerText,
finalSummary,
"Updates the summary with the result"
);
assert
.dom(".summary-box .generated-summary p")
.hasText(finalSummary, "Updates the summary with the result");
assert.ok(exists(".summary-box .summarized-on"), "summary metadata exists");
assert.dom(".summary-box .summarized-on").exists("summary metadata exists");
});
});

View File

@ -776,7 +776,7 @@ module("Integration | Component | Widget | post", function (hooks) {
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists(".topic-map"));
assert.dom(".topic-map").doesNotExist();
});
test("topic map - few posts", async function (assert) {
@ -849,7 +849,7 @@ module("Integration | Component | Widget | post", function (hooks) {
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists(".toggle-summary"));
assert.dom(".toggle-summary").doesNotExist();
});
test("topic map - has top replies summary", async function (assert) {
@ -860,7 +860,7 @@ module("Integration | Component | Widget | post", function (hooks) {
hbs`<MountWidget @widget="post" @args={{this.args}} @showTopReplies={{this.showTopReplies}} />`
);
assert.strictEqual(count(".toggle-summary"), 1);
assert.dom(".toggle-summary").exists({ count: 1 });
await click(".toggle-summary button");
assert.ok(this.summaryToggled);
@ -876,8 +876,8 @@ module("Integration | Component | Widget | post", function (hooks) {
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(count(".private-message-map"), 1);
assert.strictEqual(count(".private-message-map .user"), 1);
assert.dom(".private-message-map").exists({ count: 1 });
assert.dom(".private-message-map .user").exists({ count: 1 });
});
test("post notice - with username", async function (assert) {