Skip to content

Commit c79d289

Browse files
authored
feat: [1.x] [extensibility] feat: allow to be extended (#4025)
1 parent 46cdaf5 commit c79d289

File tree

3 files changed

+88
-16
lines changed

3 files changed

+88
-16
lines changed

framework/core/js/src/forum/compat.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ import routes from './routes';
7777
import ForumApplication from './ForumApplication';
7878
import isSafariMobile from './utils/isSafariMobile';
7979
import AccessTokensList from './components/AccessTokensList';
80+
import DiscussionsSearchItem from './components/DiscussionsSearchItem';
8081

8182
export default Object.assign(compat, {
8283
'utils/PostControls': PostControls,
@@ -116,6 +117,7 @@ export default Object.assign(compat, {
116117
'components/IndexPage': IndexPage,
117118
'components/DiscussionRenamedNotification': DiscussionRenamedNotification,
118119
'components/DiscussionsSearchSource': DiscussionsSearchSource,
120+
'components/DiscussionsSearchItem': DiscussionsSearchItem,
119121
'components/HeaderSecondary': HeaderSecondary,
120122
'components/ComposerButton': ComposerButton,
121123
'components/DiscussionList': DiscussionList,
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import app from '../../forum/app';
2+
import Component, { ComponentAttrs } from '../../common/Component';
3+
import Link from '../../common/components/Link';
4+
import highlight from '../../common/helpers/highlight';
5+
import Discussion from '../../common/models/Discussion';
6+
import Post from '../../common/models/Post';
7+
import type Mithril from 'mithril';
8+
import ItemList from '../../common/utils/ItemList';
9+
10+
export interface DiscussionsSearchItemAttrs extends ComponentAttrs {
11+
query: string;
12+
discussion: Discussion;
13+
mostRelevantPost: Post;
14+
}
15+
16+
export default class DiscussionsSearchItem extends Component<DiscussionsSearchItemAttrs> {
17+
query!: string;
18+
discussion!: Discussion;
19+
mostRelevantPost!: Post | null | undefined;
20+
21+
oninit(vnode: Mithril.Vnode<DiscussionsSearchItemAttrs, this>) {
22+
super.oninit(vnode);
23+
24+
this.query = this.attrs.query;
25+
this.discussion = this.attrs.discussion;
26+
this.mostRelevantPost = this.attrs.mostRelevantPost;
27+
}
28+
29+
view() {
30+
return (
31+
<li className="DiscussionSearchResult" data-index={'discussions' + this.discussion.id()}>
32+
<Link href={app.route.discussion(this.discussion, (this.mostRelevantPost && this.mostRelevantPost.number()) || 0)}>
33+
{this.viewItems().toArray()}
34+
</Link>
35+
</li>
36+
);
37+
}
38+
39+
discussionTitle() {
40+
return this.discussion.title();
41+
}
42+
43+
mostRelevantPostContent() {
44+
return this.mostRelevantPost?.contentPlain();
45+
}
46+
47+
viewItems(): ItemList<Mithril.Children> {
48+
const items = new ItemList<Mithril.Children>();
49+
50+
items.add('discussion-title', <div className="DiscussionSearchResult-title">{highlight(this.discussionTitle(), this.query)}</div>, 90);
51+
52+
!!this.mostRelevantPost &&
53+
items.add(
54+
'most-relevant',
55+
<div className="DiscussionSearchResult-excerpt">{highlight(this.mostRelevantPostContent() ?? '', this.query, 100)}</div>,
56+
80
57+
);
58+
59+
return items;
60+
}
61+
}
Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
import app from '../../forum/app';
2-
import highlight from '../../common/helpers/highlight';
32
import LinkButton from '../../common/components/LinkButton';
4-
import Link from '../../common/components/Link';
53
import { SearchSource } from './Search';
64
import type Mithril from 'mithril';
75
import Discussion from '../../common/models/Discussion';
6+
import DiscussionsSearchItem from './DiscussionsSearchItem';
87

98
/**
109
* The `DiscussionsSearchSource` finds and displays discussion search results in
1110
* the search dropdown.
1211
*/
1312
export default class DiscussionsSearchSource implements SearchSource {
1413
protected results = new Map<string, Discussion[]>();
14+
queryString: string | null = null;
1515

1616
async search(query: string): Promise<void> {
1717
query = query.toLowerCase();
1818

1919
this.results.set(query, []);
2020

21+
this.setQueryString(query);
22+
2123
const params = {
22-
filter: { q: query },
23-
page: { limit: 3 },
24-
include: 'mostRelevantPost',
24+
filter: { q: this.queryString || query },
25+
page: { limit: this.limit() },
26+
include: this.includes().join(','),
2527
};
2628

2729
return app.store.find<Discussion[]>('discussions', params).then((results) => {
@@ -36,26 +38,33 @@ export default class DiscussionsSearchSource implements SearchSource {
3638
const results = (this.results.get(query) || []).map((discussion) => {
3739
const mostRelevantPost = discussion.mostRelevantPost();
3840

39-
return (
40-
<li className="DiscussionSearchResult" data-index={'discussions' + discussion.id()}>
41-
<Link href={app.route.discussion(discussion, (mostRelevantPost && mostRelevantPost.number()) || 0)}>
42-
<div className="DiscussionSearchResult-title">{highlight(discussion.title(), query)}</div>
43-
{!!mostRelevantPost && (
44-
<div className="DiscussionSearchResult-excerpt">{highlight(mostRelevantPost.contentPlain() ?? '', query, 100)}</div>
45-
)}
46-
</Link>
47-
</li>
48-
);
41+
return <DiscussionsSearchItem query={query} discussion={discussion} mostRelevantPost={mostRelevantPost} />;
4942
}) as Array<Mithril.Vnode>;
5043

5144
return [
5245
<li className="Dropdown-header">{app.translator.trans('core.forum.search.discussions_heading')}</li>,
5346
<li>
54-
<LinkButton icon="fas fa-search" href={app.route('index', { q: query })}>
47+
<LinkButton icon="fas fa-search" href={app.route('index', { q: this.queryString })}>
5548
{app.translator.trans('core.forum.search.all_discussions_button', { query })}
5649
</LinkButton>
5750
</li>,
5851
...results,
5952
];
6053
}
54+
55+
includes(): string[] {
56+
return ['mostRelevantPost'];
57+
}
58+
59+
limit(): number {
60+
return 3;
61+
}
62+
63+
queryMutators(): string[] {
64+
return [];
65+
}
66+
67+
setQueryString(query: string): void {
68+
this.queryString = query + ' ' + this.queryMutators().join(' ');
69+
}
6170
}

0 commit comments

Comments
 (0)