@jasonwch/nodebb-plugin-meilisearch-r 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ 'use strict';
2
+
3
+ (function () {
4
+ var DECORATED_FLAG = 'data-meilisearch-decorated';
5
+ var HEADER_CLASS = 'meilisearch-quick-search-header';
6
+
7
+ var _hooks = null;
8
+
9
+ var PREFIX_ONLY_RE = /^in:topic-\d+\s*$/;
10
+ var SEARCH_API_URL_RE = /\/api\/search(\?|$)/;
11
+
12
+ function isComposerQuickSearch(options) {
13
+ return options && options.searchOptions &&
14
+ parseInt(options.searchOptions.composer, 10) === 1;
15
+ }
16
+
17
+ function hasResultPosts(data) {
18
+ return data && data.posts && data.posts.length > 0;
19
+ }
20
+
21
+ function decorate(options) {
22
+ var resultEl = options && options.searchElements && options.searchElements.resultEl;
23
+ if (!resultEl || !resultEl.length) { return; }
24
+ if (resultEl.attr(DECORATED_FLAG) === '1') { return; }
25
+
26
+ require(['benchpress'], function (Benchpress) {
27
+ if (!Benchpress || typeof Benchpress.render !== 'function') { return; }
28
+ // re-check after async require in case another fire raced ahead
29
+ if (resultEl.attr(DECORATED_FLAG) === '1') { return; }
30
+
31
+ Benchpress.render('client/partials/quick-search-header', {})
32
+ .then(function (html) {
33
+ // re-check after async render+translate in case another fire raced ahead
34
+ if (resultEl.attr(DECORATED_FLAG) === '1') { return; }
35
+ var header = $(html);
36
+ resultEl.find('.' + HEADER_CLASS).remove();
37
+ resultEl.prepend(header);
38
+ resultEl.attr(DECORATED_FLAG, '1');
39
+ bindResultClick(resultEl);
40
+ })
41
+ .catch(function () {
42
+ // template not available (e.g. build pending) - leave results undecorated
43
+ });
44
+ });
45
+ }
46
+
47
+ function bindResultClick(resultEl) {
48
+ resultEl
49
+ .off('click.meili-minimize')
50
+ .on('click.meili-minimize', '#quick-search-results a', function () {
51
+ var composerEl = resultEl.closest('.composer');
52
+ if (!composerEl.length) { return; }
53
+ var hideBtn = composerEl.find('[data-action="hide"]').first();
54
+ if (!hideBtn.length) { return; }
55
+ if (!_hooks) { return; }
56
+ // Minimize AFTER ajaxify navigation completes so the in-flight
57
+ // page transition isn't interrupted by composer.minimize().
58
+ // hooks.one() self-unregisters after the first (and only) fire.
59
+ _hooks.one('action:ajaxify.end', function () {
60
+ hideBtn.trigger('click');
61
+ });
62
+ });
63
+ }
64
+
65
+ function onQuickSearchComplete(payload) {
66
+ if (!isComposerQuickSearch(payload.options)) { return; }
67
+ if (!hasResultPosts(payload.data)) { return; }
68
+ decorate(payload.options);
69
+ }
70
+
71
+ function dismissVisible() {
72
+ $('.quick-search-container').filter(':not(.hidden)')
73
+ .filter('[' + DECORATED_FLAG + '="1"]')
74
+ .each(function () {
75
+ var $box = $(this);
76
+ var composer = $box.closest('.composer');
77
+ if (!composer.length) { return; }
78
+ $box.addClass('hidden');
79
+ // restore keyboard/mouse focus to the Subject field
80
+ var titleInput = composer.find('input.title').first();
81
+ if (titleInput.length) {
82
+ titleInput[0].focus();
83
+ }
84
+ });
85
+ }
86
+
87
+ function onKeydown(e) {
88
+ if (e.key !== 'Escape' && e.keyCode !== 27) { return; }
89
+ var dismissed = false;
90
+ $('.quick-search-container').filter(':not(.hidden)')
91
+ .filter('[' + DECORATED_FLAG + '="1"]')
92
+ .each(function () {
93
+ dismissed = true;
94
+ return false;
95
+ });
96
+ if (dismissed) {
97
+ e.preventDefault();
98
+ e.stopPropagation();
99
+ dismissVisible();
100
+ }
101
+ }
102
+
103
+ function patchSearchApi() {
104
+ require(['search'], function (search) {
105
+ if (!search || typeof search.api !== 'function') { return; }
106
+ if (search.api._meiliWrapped) { return; }
107
+ var originalApi = search.api;
108
+ var wrapped = function (data, callback) {
109
+ var term = String((data && data.term) || '');
110
+ if (!term.trim() || PREFIX_ONLY_RE.test(term)) {
111
+ callback({ posts: [], categories: [], matchCount: 0, pageCount: 1 });
112
+ return;
113
+ }
114
+ return originalApi.call(search, data, callback);
115
+ };
116
+ wrapped._meiliWrapped = true;
117
+ search.api = wrapped;
118
+ });
119
+ }
120
+
121
+ function hideQuickSearchSpinners() {
122
+ $('.quick-search-container').each(function () {
123
+ var $box = $(this);
124
+ $box.find('.loading-indicator').addClass('hidden');
125
+ if (!$box.find('.quick-search-results-container').children().length) {
126
+ $box.addClass('hidden');
127
+ }
128
+ });
129
+ }
130
+
131
+ function bindSearchFailGuard() {
132
+ $(document).on('ajaxError.meili-quicksearch', function (event, jqXHR, settings) {
133
+ if (!settings || !settings.url) { return; }
134
+ if (!SEARCH_API_URL_RE.test(settings.url)) { return; }
135
+ hideQuickSearchSpinners();
136
+ });
137
+ }
138
+
139
+ function init() {
140
+ if (!window.config || !window.config.searchEnabled) { return; }
141
+ if (typeof window.jQuery === 'undefined') { return; }
142
+
143
+ require(['hooks'], function (hooks) {
144
+ _hooks = hooks;
145
+ hooks.on('action:search.quick.complete', function (payload) {
146
+ onQuickSearchComplete(payload || {});
147
+ });
148
+
149
+ document.addEventListener('keydown', onKeydown);
150
+ });
151
+
152
+ patchSearchApi();
153
+ bindSearchFailGuard();
154
+ }
155
+
156
+ if (document.readyState === 'loading') {
157
+ document.addEventListener('DOMContentLoaded', init);
158
+ } else {
159
+ init();
160
+ }
161
+ })();
@@ -0,0 +1,104 @@
1
+ /* Place any SCSS in here */
2
+
3
+ .force-reindex-container {
4
+ margin-top: 0;
5
+ }
6
+
7
+ .reindex-actions {
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+ align-items: center;
11
+ justify-content: center;
12
+ gap: 1rem;
13
+ width: 100%;
14
+
15
+ #reindex {
16
+ flex: 0 0 auto;
17
+ }
18
+
19
+ @media (max-width: 767px) {
20
+ flex-direction: column;
21
+ gap: 0.75rem;
22
+ }
23
+ }
24
+
25
+ .reindex-progress-container {
26
+ transition: display 0.5s;
27
+ }
28
+ .reindex-progress-bar {
29
+ transition: width 0.1s;
30
+ }
31
+
32
+ .last-reindex-title {
33
+ margin-top: 0;
34
+ margin-bottom: 8px;
35
+ font-size: 14px;
36
+ font-weight: bold;
37
+ }
38
+
39
+ .last-reindex-table {
40
+ margin-bottom: 0;
41
+ font-size: 13px;
42
+
43
+ th {
44
+ text-align: right;
45
+ vertical-align: middle;
46
+ }
47
+
48
+ th, td {
49
+ word-break: break-word;
50
+ }
51
+
52
+ .label {
53
+ font-size: 85%;
54
+ }
55
+ }
56
+
57
+
58
+
59
+ .meilisearch-quick-search-header {
60
+ display: flex;
61
+ align-items: center;
62
+ justify-content: space-between;
63
+ padding: 0.25rem 0.5rem;
64
+ margin-bottom: 0.25rem;
65
+ border-bottom: 1px solid var(--bs-border-color, #dee2e6);
66
+
67
+ strong {
68
+ font-size: 0.9rem;
69
+ font-weight: bold;
70
+ }
71
+ }
72
+
73
+ .meilisearch-quick-search-esc {
74
+ position: absolute;
75
+ top: 0.35rem;
76
+ right: 0.5rem;
77
+ font-size: 0.7rem;
78
+ letter-spacing: 0.04em;
79
+ text-transform: uppercase;
80
+ padding: 0 0.35rem;
81
+ line-height: 1.4;
82
+ border: 1px solid var(--bs-border-color, #dee2e6);
83
+ border-radius: 0.25rem;
84
+ color: var(--bs-secondary-color, #6c757d);
85
+ background: var(--bs-body-bg, #fff);
86
+ user-select: none;
87
+ }
88
+
89
+ /* Cap dropdown to roughly 3 result rows so it never overflows past the
90
+ browser bottom bar when the composer is in half-screen mode. Activated
91
+ only on composer dropdowns (data-meilisearch-decorated="1" set by
92
+ static/lib/client/quick-search.js). */
93
+ .quick-search-container[data-meilisearch-decorated="1"] {
94
+ max-height: 320px;
95
+ overflow: hidden;
96
+ display: flex;
97
+ flex-direction: column;
98
+ }
99
+
100
+ .quick-search-container[data-meilisearch-decorated="1"] .quick-search-results {
101
+ max-height: 260px !important;
102
+ overflow: auto;
103
+ flex: 1 1 auto;
104
+ }
@@ -0,0 +1,7 @@
1
+ <form>
2
+ <div class="form-group">
3
+ <label for="rule">{{tx("meilisearch:admin.rankingRulesFormLabel")}}</label>
4
+ <input type="text" id="rule" name="rule" class="form-control" placeholder="eg. cid:asc" />
5
+ <p class="help-block">{{tx("meilisearch:admin.rankingRulesFormHelp")}} <a href="https://docs.meilisearch.com/learn/core_concepts/relevancy.html#custom-rules">https://docs.meilisearch.com/learn/core_concepts/relevancy.html#custom-rules</a></p>
6
+ </div>
7
+ </form>
@@ -0,0 +1,11 @@
1
+ <li data-type="item" class="list-group-item">
2
+ <div class="row">
3
+ <div class="col-xs-9">
4
+ <strong>{rule}</strong><br />
5
+ </div>
6
+ <div class="col-xs-3 text-right">
7
+ <button type="button" data-type="edit" class="btn btn-info">{{tx("meilisearch:admin.edit")}}</button>
8
+ <button type="button" data-type="remove" class="btn btn-danger">{{tx("meilisearch:admin.delete")}}</button>
9
+ </div>
10
+ </div>
11
+ </li>
@@ -0,0 +1,7 @@
1
+ <form>
2
+ <div class="form-group">
3
+ <label for="word">{{tx("meilisearch:admin.stopWordsFormLabel")}}</label>
4
+ <input type="text" id="word" name="word" class="form-control" placeholder="the" />
5
+ <p class="help-block">{{tx("meilisearch:admin.stopWordsFormHelp")}} <a href="https://docs.meilisearch.com/reference/api/settings.html#stop-words">https://docs.meilisearch.com/reference/api/settings.html#stop-words</a></p>
6
+ </div>
7
+ </form>
@@ -0,0 +1,11 @@
1
+ <li data-type="item" class="list-group-item">
2
+ <div class="row">
3
+ <div class="col-xs-9">
4
+ <strong>{word}</strong><br />
5
+ </div>
6
+ <div class="col-xs-3 text-right">
7
+ <button type="button" data-type="edit" class="btn btn-info">{{tx("meilisearch:admin.edit")}}</button>
8
+ <button type="button" data-type="remove" class="btn btn-danger">{{tx("meilisearch:admin.delete")}}</button>
9
+ </div>
10
+ </div>
11
+ </li>
@@ -0,0 +1,9 @@
1
+ <form>
2
+ <div class="form-group">
3
+ <label for="word">{{tx("meilisearch:admin.synonymsWordFormLabel")}}</label>
4
+ <input type="text" id="word" name="word" class="form-control" placeholder="word" />
5
+ <label for="synonyms">{{tx("meilisearch:admin.synonymsSynonymsFormLabel")}}</label>
6
+ <input type="text" id="synonyms" name="synonyms" class="form-control" placeholder="term,utterance" />
7
+ <p class="help-block">{{tx("meilisearch:admin.synonymsFormHelp")}}</p>
8
+ </div>
9
+ </form>
@@ -0,0 +1,12 @@
1
+ <li data-type="item" class="list-group-item">
2
+ <div class="row">
3
+ <div class="col-xs-9">
4
+ <strong>{word}</strong><br />
5
+ <small>{synonyms}</small>
6
+ </div>
7
+ <div class="col-xs-3 text-right">
8
+ <button type="button" data-type="edit" class="btn btn-info">{{tx("meilisearch:admin.edit")}}</button>
9
+ <button type="button" data-type="remove" class="btn btn-danger">{{tx("meilisearch:admin.delete")}}</button>
10
+ </div>
11
+ </div>
12
+ </li>
@@ -0,0 +1,6 @@
1
+ <form>
2
+ <div class="form-group">
3
+ <label for="word">{{tx("meilisearch:admin.typoToleranceDisableOnWordsFormLabel")}}</label>
4
+ <input type="text" id="word" name="word" class="form-control" placeholder="the" />
5
+ </div>
6
+ </form>
@@ -0,0 +1,11 @@
1
+ <li data-type="item" class="list-group-item">
2
+ <div class="row">
3
+ <div class="col-xs-9">
4
+ <strong>{word}</strong><br />
5
+ </div>
6
+ <div class="col-xs-3 text-right">
7
+ <button type="button" data-type="edit" class="btn btn-info">{{tx("meilisearch:admin.edit")}}</button>
8
+ <button type="button" data-type="remove" class="btn btn-danger">{{tx("meilisearch:admin.delete")}}</button>
9
+ </div>
10
+ </div>
11
+ </li>
@@ -0,0 +1,184 @@
1
+ <div class="card">
2
+ <div class="card-header">
3
+ <h2 class="card-title">{{tx("meilisearch:admin.actions")}}</h2>
4
+ </div>
5
+ <div class="card-body">
6
+ <div class="row">
7
+ <div class="col-sm-2 col-xs-12 settings-header">{{tx("meilisearch:admin.index")}}</div>
8
+ <div class="col-sm-10 col-xs-12">
9
+ <div class="row">
10
+ <div class="col-sm-{{{ if lastReindexResult.finishedAt }}}8{{{ else }}}12{{{ end }}} col-xs-12">
11
+ <p class="help-block">{{tx("meilisearch:admin.reindexHelp")}}</p>
12
+ <div class="reindex-actions">
13
+ <button type="button" id="reindex" class="btn btn-danger btn-sm">{{tx("meilisearch:admin.reindex")}}</button>
14
+ </div>
15
+ <div class="text-center">
16
+ <div class="checkbox force-reindex-container" id="reindex-force-container">
17
+ <label for="force-reindex" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
18
+ <input type="checkbox" class="mdl-switch__input" id="force-reindex" name="force-reindex">
19
+ <span class="mdl-switch__label"><strong>{{tx("meilisearch:admin.forceReindex")}}</strong></span>
20
+ </label>
21
+ </div>
22
+ </div>
23
+ <div class="col-sm-12 col-xs-12 reindex-progress-container {{{ if !indexing.running}}}hidden{{{end}}}">
24
+ <h4 class="text-center">{{tx("meilisearch:admin.reindexTopicsProgress")}} <span id="topic-reindex-progress-text">{indexing.topic_progress.current}/{indexing.topic_progress.total}</span></h4>
25
+ <div class="progress">
26
+ <div id="topic-reindex-progress" class="progress-bar reindex-progress-bar" role="progressbar" aria-valuenow="{indexing.topic_progress.current}" aria-valuemin="0" aria-valuemax="{indexing.topic_progress.total}" style="width: {{{ if topicPercent }}}{topicPercent}%{{{ else }}}0%{{{ end }}};">
27
+ {indexing.topic_progress.current}/{indexing.topic_progress.total}
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <div class="col-sm-12 col-xs-12 reindex-progress-container {{{ if !indexing.running}}}hidden{{{end}}}">
32
+ <h4 class="text-center">{{tx("meilisearch:admin.reindexPostsProgress")}} <span id="post-reindex-progress-text">{indexing.post_progress.current}/{indexing.post_progress.total}</span></h4>
33
+ <div class="progress">
34
+ <div id="post-reindex-progress" class="progress-bar reindex-progress-bar" role="progressbar" aria-valuenow="{indexing.post_progress.current}" aria-valuemin="0" aria-valuemax="{indexing.post_progress.total}" style="width: {{{ if postPercent }}}{postPercent}%{{{ else }}}0%{{{ end }}};">
35
+ {indexing.post_progress.current}/{indexing.post_progress.total}
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ {{{ if lastReindexResult.finishedAt }}}
41
+ <div class="col-sm-4 col-xs-12">
42
+ <h4 class="text-center last-reindex-title">{{tx("meilisearch:admin.lastReindex")}}</h4>
43
+ <div class="table-responsive">
44
+ <table class="table table-bordered table-condensed last-reindex-table">
45
+ <tbody>
46
+ <tr>
47
+ <th>{{tx("meilisearch:admin.lastReindexDate")}}</th>
48
+ <td><span data-finished-at="{lastReindexResult.finishedAt}">&mdash;</span></td>
49
+ </tr>
50
+ <tr>
51
+ <th>{{tx("meilisearch:admin.lastReindexTopics")}}</th>
52
+ <td>{lastReindexResult.topic_progress.current}/{lastReindexResult.topic_progress.total}</td>
53
+ </tr>
54
+ <tr>
55
+ <th>{{tx("meilisearch:admin.lastReindexPosts")}}</th>
56
+ <td>{lastReindexResult.post_progress.current}/{lastReindexResult.post_progress.total}</td>
57
+ </tr>
58
+ {{{ if lastReindexResult.skippedDeletedTopics }}}
59
+ <tr>
60
+ <th>{{tx("meilisearch:admin.lastReindexSkippedDeletedTopics")}}</th>
61
+ <td>{lastReindexResult.skippedDeletedTopics}</td>
62
+ </tr>
63
+ {{{ end }}}
64
+ {{{ if lastReindexResult.skippedDeletedPosts }}}
65
+ <tr>
66
+ <th>{{tx("meilisearch:admin.lastReindexSkippedDeletedPosts")}}</th>
67
+ <td>{lastReindexResult.skippedDeletedPosts}</td>
68
+ </tr>
69
+ {{{ end }}}
70
+ <tr>
71
+ <th>{{tx("meilisearch:admin.lastReindexStatus")}}</th>
72
+ <td>
73
+ {{{ if lastReindexResult.success }}}
74
+ <span class="label label-success">{{tx("meilisearch:admin.lastReindexSuccess")}}</span>
75
+ {{{ else }}}
76
+ <span class="label label-danger">{{tx("meilisearch:admin.lastReindexFailed")}}</span>
77
+ {{{ end }}}
78
+ </td>
79
+ </tr>
80
+ {{{ if lastReindexResult.error }}}
81
+ <tr>
82
+ <th>{{tx("meilisearch:admin.lastReindexError")}}</th>
83
+ <td class="text-danger">{lastReindexResult.error}</td>
84
+ </tr>
85
+ {{{ end }}}
86
+ </tbody>
87
+ </table>
88
+ </div>
89
+ </div>
90
+ {{{ end }}}
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ <div class="card">
97
+ <div class="card-header">
98
+ <h2 class="card-title">{{tx("meilisearch:admin.settings")}}</h2>
99
+ </div>
100
+ <div class="card-body">
101
+ <form role="form" class="meilisearch-settings">
102
+ <div class="row">
103
+ <div class="col-sm-2 col-xs-12 settings-header">{{tx("meilisearch:admin.connection")}}</div>
104
+ <div class="col-sm-10 col-xs-12">
105
+ <div class="form-group">
106
+ <label for="host">{{tx("meilisearch:admin.host")}}</label>
107
+ <input type="text" id="host" name="host" title="Host" class="form-control" placeholder="http://localhost:7700">
108
+ </div>
109
+ <div class="form-group">
110
+ <label for="apiKey">{{tx("meilisearch:admin.apiKey")}}</label>
111
+ <input type="password" id="apiKey" name="apiKey" title="API Key" class="form-control" placeholder="*****">
112
+ </div>
113
+ <div class="form-group">
114
+ <label for="healthCheckInterval">{{tx("meilisearch:admin.healthCheckInterval")}}</label>
115
+ <input type="number" id="healthCheckInterval" name="healthCheckInterval" title="Health Check Interval" class="form-control" placeholder="60">
116
+ </div>
117
+ </div>
118
+ </div>
119
+
120
+ <br />
121
+
122
+ <div class="row">
123
+ <div class="col-sm-2 col-xs-12 settings-header">{{tx("meilisearch:admin.search")}}</div>
124
+ <div class="col-sm-10 col-xs-12">
125
+ <div class="form-group">
126
+ <label for="maxDocuments">{{tx("meilisearch:admin.maxDocuments")}}</label>
127
+ <input type="number" id="maxDocuments" name="maxDocuments" title="Max Documents" class="form-control" placeholder="500">
128
+ </div>
129
+ <div class="form-group">
130
+ <label for="searchMinTermLength">{{tx("meilisearch:admin.searchMinTermLength")}}</label>
131
+ <input type="number" id="searchMinTermLength" name="searchMinTermLength" min="2" title="{{tx("meilisearch:admin.searchMinTermLength")}}" class="form-control" placeholder="2">
132
+ <p class="help-block">{{tx("meilisearch:admin.searchMinTermLengthHelp")}}</p>
133
+ </div>
134
+ <div class="form-group" data-type="sorted-list" data-sorted-list="rankingRules" data-item-template="admin/plugins/meilisearch/partials/rankingRules/item" data-form-template="admin/plugins/meilisearch/partials/rankingRules/form">
135
+ <label for="rankingRulesList">{{tx("meilisearch:admin.rankingRules")}}</label>
136
+ <p class="help-block">{{tx("meilisearch:admin.rankingRulesHelp")}} <a href="https://docs.meilisearch.com/learn/core_concepts/relevancy.html#ranking-rules">https://docs.meilisearch.com/learn/core_concepts/relevancy.html#ranking-rules</a></p>
137
+ <ul name="rankingRulesList" data-type="list" class="list-group"></ul>
138
+ <button type="button" data-type="add" class="btn btn-info">{{tx("meilisearch:admin.addRankingRule")}}</button>
139
+ </div>
140
+ <div class="form-group" data-type="sorted-list" data-sorted-list="stopWords" data-item-template="admin/plugins/meilisearch/partials/stopWords/item" data-form-template="admin/plugins/meilisearch/partials/stopWords/form">
141
+ <label for="stopWordsList">{{tx("meilisearch:admin.stopWords")}}</label>
142
+ <p class="help-block">{{tx("meilisearch:admin.stopWordsHelp")}} <a href="https://docs.meilisearch.com/reference/api/settings.html#get-stop-words">https://docs.meilisearch.com/reference/api/settings.html#get-stop-words</a></p>
143
+ <ul name="stopWordsList" data-type="list" class="list-group"></ul>
144
+ <button type="button" data-type="add" class="btn btn-info">{{tx("meilisearch:admin.addStopWord")}}</button>
145
+ </div>
146
+ <div class="form-group" data-type="sorted-list" data-sorted-list="synonyms" data-item-template="admin/plugins/meilisearch/partials/synonyms/item" data-form-template="admin/plugins/meilisearch/partials/synonyms/form">
147
+ <label for="synonymsList">{{tx("meilisearch:admin.synonyms")}}</label>
148
+ <p class="help-block">{{tx("meilisearch:admin.synonymsHelp")}} <a href="https://docs.meilisearch.com/learn/configuration/synonyms.html">https://docs.meilisearch.com/learn/configuration/synonyms.html</a></p>
149
+ <ul name="synonymsList" data-type="list" class="list-group"></ul>
150
+ <button type="button" data-type="add" class="btn btn-info">{{tx("meilisearch:admin.addSynonym")}}</button>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ <div class="row">
155
+ <div class="col-sm-2 col-xs-12 settings-header">{{tx("meilisearch:admin.typoTolerance")}}</div>
156
+ <div class="col-sm-10 col-xs-12">
157
+ <div class="checkbox" id="typoTolerance-container">
158
+ <label for="typoTolerance" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
159
+ <input type="checkbox" class="mdl-switch__input" id="typoTolerance" name="typoTolerance">
160
+ <span class="mdl-switch__label"><strong>{{tx("meilisearch:admin.typoToleranceEnable")}}</strong></span>
161
+ </label>
162
+ </div>
163
+ <div class="form-group">
164
+ <label for="typoToleranceMinWordSizeOneTypo">{{tx("meilisearch:admin.typoToleranceMinWordSizeOneTypo")}}</label>
165
+ <input type="number" id="typoToleranceMinWordSizeOneTypo" name="typoToleranceMinWordSizeOneTypo" title="Typo Tolerance Min Word Size One Typo" class="form-control" placeholder="5">
166
+ </div>
167
+ <div class="form-group">
168
+ <label for="typoToleranceMinWordSizeTwoTypos">{{tx("meilisearch:admin.typoToleranceMinWordSizeTwoTypos")}}</label>
169
+ <input type="number" id="typoToleranceMinWordSizeTwoTypos" name="typoToleranceMinWordSizeTwoTypos" title="Typo Tolerance Min Word Size Two Typos" class="form-control" placeholder="9">
170
+ </div>
171
+ <div class="form-group" data-type="sorted-list" data-sorted-list="typoToleranceDisableOnWords" data-item-template="admin/plugins/meilisearch/partials/typoToleranceDisableOnWords/item" data-form-template="admin/plugins/meilisearch/partials/typoToleranceDisableOnWords/form">
172
+ <label for="typoToleranceDisableOnWordsList">{{tx("meilisearch:admin.typoToleranceDisableOnWords")}}</label>
173
+ <p class="help-block">{{tx("meilisearch:admin.typoToleranceDisableOnWordsHelp")}} <a href="https://docs.meilisearch.com/learn/configuration/typo_tolerance.html#disableonwords">https://docs.meilisearch.com/learn/configuration/typo_tolerance.html#disableonwords</a></p>
174
+ <ul name="typoToleranceDisableOnWordsList" data-type="list" class="list-group"></ul>
175
+ <button type="button" data-type="add" class="btn btn-info">{{tx("meilisearch:admin.addTypoToleranceDisabledWord")}}</button>
176
+ </div>
177
+ </div>
178
+ </div>
179
+ </form>
180
+ <button id="save" class="floating-button mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
181
+ <i class="material-icons">{{tx("meilisearch:admin.save")}}</i>
182
+ </button>
183
+ </div>
184
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="meilisearch-quick-search-header">
2
+ <strong>{{tx("meilisearch:similar-topics-header")}}</strong>
3
+ <span class="meilisearch-quick-search-esc">{{tx("meilisearch:esc")}}</span>
4
+ </div>